Відповідно до глави 9 (Парсер та оптимізатор), Саша Пачов , сторінка 172 Книги Розуміння внутрішніх справ MySQL
ось розбивка оцінки запиту як наступних завдань:
- Визначте, які ключі можна використовувати для отримання записів із таблиць, і виберіть найкращу для кожної таблиці.
- Для кожної таблиці вирішіть, чи краще сканування таблиці, ніж читання на ключі. Якщо є багато записів, які відповідають значенню ключа, переваги ключа зменшуються, а сканування таблиці стає швидшим.
- Визначте порядок, в якому слід з'єднати таблиці, коли в запиті присутнє більше однієї таблиці.
- Перепишіть пункти WHERE для усунення мертвого коду, зменшуючи непотрібні обчислення та змінюючи обмеження, де це можливо, щоб відкрити шлях використання ключів.
- Виключіть невикористані таблиці із з'єднання.
- Визначте, чи можна використовувати ключі для
ORDER BY
та GROUP BY
.
- Спроба спростити підзапити, а також визначити, в якій мірі їх результати можна кешувати.
- Об’єднати перегляди (розгорніть посилання перегляду як макросу)
На цій самій сторінці написано наступне:
У термінології оптимізатора MySQL кожен запит - це набір об'єднань. Термін приєднання використовується тут ширше, ніж у командах SQL. Запит лише на одній таблиці - це вироджене приєднання. Хоча ми зазвичай не вважаємо читання записів з однієї таблиці як об'єднанням, ті ж структури та алгоритми, які використовуються при звичайних з'єднаннях, прекрасно працюють для вирішення запиту лише однією таблицею.
ЕПІЛОГ
Через наявні ключі, кількість даних та вираження запиту, MySQL Joins іноді може робити щось для власного блага (або щоб повернутися до нас) та отримати результати, яких ми не очікували і не можемо швидко пояснити.
Я писав про цю химерність раніше
оскільки оптимізатор запитів MySQL міг зробити відхилення певних ключів під час оцінки запиту.
@ Коментар Phil допоможе мені зрозуміти, як розмістити цю відповідь (+1 для коментаря @ Phil)
Коментар @ ypercube (+1 також для цього) є компактною версією моєї публікації, оскільки оптимізатор запитів MySQL примітивний. На жаль, це має бути, оскільки це стосується двигунів зовнішнього зберігання.
ВИСНОВОК
Що стосується вашого актуального питання, оптимізатор запитів MySQL визначав би показники ефективності кожного запиту, коли він виконаний
- підрахунок рядків
- вибір клавіш
- масаж наборів результатів
- О так, роблячи фактичний ПРИЄДНАЙТЕ
Ймовірно, вам доведеться примусити виконувати порядок виконання, переписавши (рефакторинг) запит
Ось перший запит, який ви дали
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
where b.tag = 'Y';
Спробуйте переписати його, щоб спочатку оцінити ДЕЙ
select count(*)
from table1 a
join (select key_col from table2 where tag='Y') b
on b.key_col=a.key_col;
Це, безумовно, змінить план ПОЯСНЕННЯ. Це може дати кращі або гірші результати.
Одного разу я відповів на питання в StackOverflow, де я застосував цю методику. ПОЯСНЕНО було жахливим, але вистава була динамітною. Це спрацювало лише через те, що присутні правильні індекси та використання LIMIT у підзапиті .
Як і у випадку з цінами на акції, якщо мова заходить про запити та намагається їх висловити, застосовуються обмеження, результати можуть відрізнятися, а минула ефективність не свідчить про майбутні результати.