MIN / MAX против ORDER BY и LIMIT


101

Какой из следующих запросов вы бы сочли лучшим? Каковы ваши причины (эффективность кода, лучшая ремонтопригодность, меньше WTFery) ...

SELECT MIN(`field`)
FROM `tbl`;

SELECT `field`
FROM `tbl`
ORDER BY `field`
LIMIT 1;

Ответы:


129

В худшем случае, когда вы смотрите на неиндексированное поле, использование MIN()требует одного полного прохода таблицы. Использование SORTи LIMITтребует сортировки файлов. Если работать с большим столом, вероятно, будет значительная разница в воспринимаемой производительности. В качестве бессмысленной точки данных, MIN()потребовалось 0,36 секунды SORTи LIMIT0,84 секунды против таблицы из 106000 строк на моем сервере разработки.

Однако если вы смотрите на индексированный столбец, разницу заметить труднее (бессмысленная точка данных составляет 0,00 с в обоих случаях). Однако, глядя на вывод объяснения, похоже, что MIN()он может просто извлечь наименьшее значение из индекса (`` Выбрать таблицы, оптимизированные '' и `` NULL '' строки), тогда как SORTи LIMITвсе еще необходимо выполнить упорядоченный обход индекса. (106000 строк). Фактическое влияние на производительность, вероятно, незначительно.

Похоже, MIN()это правильный путь - он быстрее в худшем случае, неотличим в лучшем случае, является стандартным SQL и наиболее четко выражает ценность, которую вы пытаетесь получить. Единственный случай, когда кажется, что использование SORTи LIMITбыло бы желательным, - это, как упоминалось в mson , когда вы пишете общую операцию, которая находит верхние или нижние значения N из произвольных столбцов, и не стоит записывать операцию специального случая.


7
o (n) для одного прохода против 0 (nlogn) для сортировки
Abhishek Iyer

1
@AbhishekIyer, вы совершенно правы, но я бы добавил «в худшем случае для неиндексированного поля».
dmikam

Часть о худшем неиндексированном случае неверна. Вам всегда нужно полное сканирование, как еще вы знаете, что это минимум или максимум? Не то чтобы вы сканируете, а ценность кричит: «Эй, ты наконец нашел меня! Я Джек, максимум!».
Робо Робок,

В тесте с индексированной таблицей с 470 миллионами строк оба запроса занимают 0,00 с. Однако, если мы добавим к запросам фильтр «WHERE field2 = x», запрос с LIMIT все равно займет 0,00 с, а запрос с MIN - 0,21 с.
Антонио Каньяс Варгас

13
SELECT MIN(`field`)
FROM `tbl`;

Просто потому, что он совместим с ANSI. Ограничение 1 характерно для MySql, как TOP для SQL Server.


Большинство СУБД имеют ограничение / смещение или эквивалент, и он используется в большинстве приложений, над которыми я работал (не как альтернатива MIN, а для других целей, таких как разбиение на страницы)
finnw

@finnw - Я согласен, но пример спрашивающего явно сравнивал limit с min.
Отавио Десио

9

Как отметили mson и Sean McSomething , MIN предпочтительнее.

Еще одна причина, по которой ORDER BY + LIMIT полезен, - это если вы хотите получить значение столбца, отличного от столбца MIN.

Пример:

SELECT some_other_field, field
FROM tbl
ORDER BY field
LIMIT 1

4

Думаю, ответы зависят от того, что вы делаете.

Если у вас есть одноразовый запрос и цель настолько проста, насколько вы указали, предпочтительнее выбрать min (поле).

Однако обычно эти типы требований меняются на - захват первых n результатов, захват n-го - m-го результатов и т. Д.

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

Зачем ограничивать себя сейчас, потому что боль вы можете почувствовать или не почувствовать позже?

Я думаю, что лучше оставаться в стандарте ANSI, насколько это возможно, но это всего лишь рекомендация ...


3

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.