МІН / МАКС проти ЗАМОВЛЕННЯ НА ОБМЕЖЕННЯ


100

З наведених нижче запитів, який із методів Ви вважаєте кращим? Які ваші причини (ефективність коду, краща ремонтопридатність, менше WTFery) ...

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

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

Відповіді:


126

У гіршому випадку, коли ви переглядаєте неіндексоване поле, використання MIN()вимагає одного повного проходу таблиці. Використання SORTі LIMITвимагає сортування файлів. Якщо натрапити на великий стіл, то, ймовірно, буде суттєва різниця у оцінюваній ефективності. Як безглуздий пункт даних, MIN()зайняв .36s SORTі LIMITвзяв .84s проти 106000 рядкової таблиці на моєму сервері розробників.

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

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


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

1
@AbhishekIyer ви цілком праві, але я додав би "в гіршому випадку для неіндексованого поля".
dmikam

Ця частина про найгірший неіндексований випадок є неправильною. Завжди потрібне повне сканування, як ще ви знаєте, що це мінімальне чи максимальне значення? Це не схоже на те, що ви скануєте, і значення кричить: "Гей, ти нарешті знайшов мене! Я Джек, макс!".
Robo Robok

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

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

Просто тому, що він сумісний з ANSI. Обмеження 1 стосується MySql, як TOP для SQL Server.


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

@finnw - я згоден, але приклад запитувача явно порівнював ліміт з min.
Otávio Décio


4

Думаю, відповіді залежать від того, що ви робите.

Якщо у вас запит на 1 вимкнення, а намір настільки простий, як ви вказали, переважно вибрати min (поле).

Однак загальновизнано, що ці типи вимог змінюються на - захоплювати верхні n результатів, захоплювати nth - mth результати тощо.

Я не думаю, що це надто жахлива ідея прив’язуватися до вибраної вами бази даних. Зміна баз даних не слід робити легковажно, і потрібно переглядати ціну, яку ви платите, коли робите цей крок.

Навіщо обмежуватись зараз, бо біль, який ти можеш відчувати чи не відчувати пізніше?

Я вважаю, що добре залишатися ANSI якомога більше, але це лише орієнтир ...


3

Враховуючи прийнятну ефективність, я б використав першу, оскільки вона семантично наближається до наміру.
Якщо продуктивність була проблемою, (більшість сучасних оптимізаторів, можливо, оптимізуватимуть обидва до одного і того ж плану запиту, хоча вам доведеться протестувати, щоб перевірити це), тоді, звичайно, я б використав швидший.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.