Приемлемая техника для группового максимума в MySQL - PullRequest
0 голосов
/ 10 января 2012

Поскольку "все знают", вы не можете возвращать не сгруппированные неагрегированные столбцы в GROUP BY, другими словами, "дайте мне идентификатор, имя и адрес сотрудника с самой высокой зарплатой в каждом отделе«.Конечно, это не совсем так: http://dev.mysql.com/doc/refman/5.1/en/group-by-hidden-columns.html Но это содержит довольно зловещее предупреждение:

Сервер может свободно выбирать любое значение из каждой группы, поэтому, если они не совпадаютвыбранные значения являются неопределенными.

В MySQL есть еще одна статья по этой проблеме: http://dev.mysql.com/doc/refman/5.0/en/example-maximum-column-group-row.html Но методика, рекомендованная там, на самом деле не использует преимущества всех скрытых столбцов.В этой статье есть комментарий от Кейси Спикмана, который рекомендует использовать упорядоченный подзапрос, например:

select deptno, emp_id, address, name from
(select * from emp order by salary desc)
group by deptno

Мои вопросы: а) Могу ли я безопасно положиться на MySQL, чтобы выбрать «первую» строку из каждогоgroup, так как подзапрос упорядочен, и b) в целом, и при условии соответствующих индексов, вероятно ли, что это будет работать лучше, чем, скажем, метод LEFT JOIN, упомянутый в той же статье?

1 Ответ

1 голос
/ 10 января 2012

Недавно было обсуждение подобного вопроса: SQL: Каков порядок по умолчанию запросов?

Но, тем не менее, я думаю, что ранжирование запросов является примером запросов в MySQL, где весьма полезно полагаться на прогнозируемый порядок (прогнозируемый с использованием определенных индексов).

Посмотрите на мой ответ на следующий вопрос: Получение последней записи в каждой группе

Вот ответы на ваши вопросы:

  1. да, иногда вы можете рассчитывать на заказ, если знаете двигатель и используемые индексы, хотя обычно он не является дружественным

  2. когда в каждой группе много элементов, решение LEFT JOIN может занять слишком много времени для выполнения, поэтому использование голых индексов может стать практически единственным решением. Но решение не должно генерировать огромные промежуточные временные таблицы.

Но ваш запрос:

select deptno, emp_id, address, name from
(select * from emp order by salary desc)
group by deptno

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...