SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 26.11.2010 16:40:13

relax
Участник
Зарегистрирован: 01.11.2010
Сообщений: 19

group+order+index

Как именно в mysql решается такое.
У нас есть select * from `table` order by `sort` LIMIT 30
sort индекс, таблица не heap. все волшебно, пока не приходится использовать group by `a` , и поскольку в group и в sort различные выражения, сортировка не может пойти по индексу, что дает нам filesort и в 10 раз замедление.
этот group отсечет 1% записей всего, и даже так  SELECT * FROM (select * from order by `sort` LIMIT 30) as `tbl` GROUP BY `a` нельзя, так как нужно ровно 30 записей, а без LIMIT внутри оно аналогично медленно.

Отредактированно relax (26.11.2010 16:40:47)

Неактивен

 

#2 26.11.2010 16:59:13

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: group+order+index

А что мешает сделать индекс на (a, `sort`)?

Неактивен

 

#3 26.11.2010 19:10:40

relax
Участник
Зарегистрирован: 01.11.2010
Сообщений: 19

Re: group+order+index

либо последняя чашка кофе была лишней, либо я на сервере тестовом перехимичил с настройками, либо я уже не знаю.

SELECT `tblA`.*,`tblB`.* FROM `tblA` LEFT JOIN `tblB` ON `tblA`.`tblB_id`=`tblB`.`id` WHERE `tblA`.`cond`='1' GROUP BY `tblA`.`tblb_id` ORDER  BY `tblA`.`sort` DESC LIMIT 30

То есть три поля, `tblb_id`-связывание + группировка, cond-условие, sort-сортировка.
Какой максимальный по длине составной ключ можно использовать?

Неактивен

 

#4 26.11.2010 20:12:10

relax
Участник
Зарегистрирован: 01.11.2010
Сообщений: 19

Re: group+order+index

where-group-order было с утра, вроде бы. Вроде бы ограничение, что group и order не должны быть разными еще действуте или как для ключа?

Отредактированно relax (26.11.2010 20:52:23)

Неактивен

 

#5 27.11.2010 03:39:54

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: group+order+index

Да, видимо, пятница. Когда бегло читаешь вопрос — понимаешь, что простого
индекса хватит. Когда задумываешься — понимаешь, что вопрос составлен с
подвохом smile Ступил, каюсь smile

По стандарту, Вы обязаны в запросе с группировкой каждую колонку вывода
или поставить в условие группировки, или написать вокруг нее аггрегирующую
функцию. То, что MySQL позволяет не писать функцию, еще не значит, что
так правильно делать smile

В частности, ответ на Ваш вопрос — никак, потому что агрегированный столбец
не привязывается к индексу по определению. Например, какую строку по-Вашему
должен выбрать MySQL, если tblB_id у двух строк одинаковые, cond = 1, а sort
разные?

Максимально возможная длина ключа — 767 байт.

Неактивен

 

#6 27.11.2010 11:20:14

relax
Участник
Зарегистрирован: 01.11.2010
Сообщений: 19

Re: group+order+index

Ну обычно пишут "GROUP BY изменяет поведение, если в выводе есть аггрегирующая функция". Фигня.
Если представлять в терминах множеств или массивов, то что делает GROUP BY `a`? собирает под-массив или под-множество(как обычная выборка) по уникальным значениям  поля `a`. Если есть аггрегирующая функция-применяется к под-множеству. Если нету-делается "приведение типа" -вместо массива получается строка.
Вполне себе нормально.
Я уже понял, что никак, но меня устроит любая из двух, только бы не тупил он при этом без индекса. А это никак не сделать.

Неактивен

 

#7 27.11.2010 11:42:24

relax
Участник
Зарегистрирован: 01.11.2010
Сообщений: 19

Re: group+order+index

P.S. Посоветуйте литературу на выходные почитать, где именно про особенности mysql хорошо прописано, с версиями, с применением каких-то конструкций под решение типовых задач с учетом специфики.
А то миграция плохо идет.

Неактивен

 

#8 27.11.2010 13:58:27

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: group+order+index

Не представляю себе, как из массива (3.1415, 2.7182, 8.31, 1.38) сделать строку
приведением типа sad

MySQL в этом плане не отличается ни от одной другой базы. Подумайте, как можно
сделать дерево так, чтобы потом можно было использовать его после группировки.
Ответ, очевидно, никак, но если Вы придумаете — Вы сделаете огромный скачок
в развитии СУБД smile

Чтобы ускорить миграцию — можно придумать какие-то разумные денормализации.
Например, сделать SELECT DISTINCT tblb_id FROM tbl_a в отдельную табличку, сде-
лать над ней индекс, а потом объединяться с ней.

Насчет «почитать» — я всегда рекомендую книжки Поля Дюбуа (Paul Dubois).

Неактивен

 

#9 28.11.2010 03:19:26

relax
Участник
Зарегистрирован: 01.11.2010
Сообщений: 19

Re: group+order+index

Да спокойно. В любом языке, который с типами обращается вольно, такое можно. из строки же получение массива приведением типа вас не смущает? smile
Да никак, это ясно.
Денормализацю сделал, понравилось. Избыточность в запросе сделал, тоже понравилось.
Поля Дюбуа с первого захода не нашел в книжном, а жаль. Зато другое нашел по работе smile

Такой вопрос.
SELECT `a`,`b`,`c` FROM `table` WHERE `b`=1 ORDER BY `c`
Индекс (`b`,`c`,`a`) идеален-вся инфа извлекается из индекса, быстро

SELECT `a`,`b`,`c` FROM `table` WHERE `b` IN(1,2) ORDER BY `c`
очевидно, тот же индекс не пойдет, условие IN и все что даст индекс+using index, но полезет filesort.

FORCE INDEX  для  (`c`,`b`,`a`) -я хочу убедить mysql, что считаю логичным сначала сортировку сделать, потом where.
он такое умеет?  И еще-вроде как бы составные индексы строятся по прямой сумме байтов, то есть если на `c` 5 байтов отводится, то правая часть без 5 байтов тоже индекс, соответственно после сортировки он where по индексу сможет делать?
Спасибо.

Неактивен

 

#10 29.11.2010 13:19:57

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: group+order+index

С массивами: перевод строки в массив — однозначная операция добавления скобочек
вокруг единственного значения. А вот обратное не работает. Так же, как любой огурец —
овощ, но не любой овощ — огурец.

FORCE INDEX умеет, разумеется smile

Индекс строится как одно дерево, значения которого являются конкатенацией байтов.
Поэтому если Вы зафиксировали одно значение через WHERE — вы выбрали ветку, кото-
рая сама себе дерево, и по которому можно сортировать. Если же через WHERE Вы выбра-
ли две ветки, то перекрестные значения из двух деревьев можно сортировать только в
памяти. Тут можно придумать алгоритм-улучшение (например, бежать одновременно по
двум деревьям и сравнивать только точечные значения), но в MySQL он не реализован.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson