@Pierre 303 вже сказав це, але я знову скажу. DO використовувати індекси на комбінаціях стовпців. Комбінований індекс у (a, b)
лише дещо повільніший для запитів, a
ніж індекс a
поодинці, і значно краще, якщо ваш запит поєднує обидва стовпці. Деякі бази даних можуть приєднуватися до індексівa
і b
до того, як потрапити в таблицю, але це не так добре, як комбінований індекс. Під час створення комбінованого індексу слід розмістити стовпець, який, швидше за все, спочатку буде шукати в комбінованому індексі.
Якщо ваша база даних підтримує її, DO ставить індекси функцій, які відображаються в запитах, а не в стовпцях. (Якщо ви викликаєте функцію в стовпці, індекси цього стовпця марні.)
Якщо ви використовуєте базу даних з справжніми тимчасовими таблицями, які ви можете створювати та знищувати на ходу (наприклад, PostgreSQL, MySQL, але не Oracle), то DO створюйте індекси на тимчасових таблицях.
Якщо ви використовуєте базу даних, яка це дозволяє (наприклад, Oracle), DO блокуйте у хороших планах запитів. Оптимізатори запитів із часом змінять плани запитів. Зазвичай вони покращують план. Але іноді вони роблять це значно гірше. Зазвичай ви не помітите вдосконалення плану - запит не був вузьким місцем. Але один поганий план може зняти зайнятий сайт.
НЕ ДАЙТЕ майте індексів на таблицях, на яких ви збираєтеся робити велике завантаження даних. Це набагато, набагато швидше скинути індекси, завантажити дані, потім відновити індекси, ніж підтримувати їх під час завантаження таблиці.
НЕ використовуйте індекси для запитів, які мають доступ до більш ніж невеликої частки великої таблиці. (Наскільки маленька залежить від обладнання. 5% - це гідне правило.) Наприклад, якщо у вас є дані з іменами та статтю, імена є хорошим кандидатом для індексації, оскільки будь-яке ім'я становить невелику частку від загальних рядків. Не було б корисно індексувати стать, оскільки вам все одно доведеться отримувати доступ до 50% рядків. Ви дійсно хочете замість цього використовувати повне сканування таблиці. Причина полягає в тому, що індекси завершують доступ до великого файлу випадковим чином, в результаті чого вам потрібно шукати диски. Пошук диска повільний. Як приклад я нещодавно мені вдалося пришвидшити запит на годину, який виглядав так:
SELECT small_table.id, SUM(big_table.some_value)
FROM small_table
JOIN big_table
ON big_table.small_table_id = small_table.id
GROUP BY small_table.id
до 3 хвилин, переписавши його наступним чином:
SELECT small_table.id, big_table_summary.summed_value
FROM small_table
JOIN (
SELECT small_table_id, SUM(some_value) as summed_value
FROM big_table
GROUP BY small_table_id
) big_table_summary
ON big_table_summary.small_table_id = small_table.id
що змусило базу даних зрозуміти, що вона не повинна намагатися використовувати спокусливий індекс на big_table.small_table_id
. (Хороша база даних, наприклад, Oracle, повинна вирішити це самостійно. Цей запит виконувався на MySQL.)
Оновлення: Ось пояснення щодо пошуку диска, який я зробив. Індекс дає швидкий пошук, щоб сказати, де дані перебувають у таблиці. Зазвичай це виграш, оскільки ви будете дивитись лише на ті дані, які вам потрібно переглянути. Але не завжди, особливо якщо ви зрештою подивитесь на багато даних. Диски добре передають дані, але роблять пошуки повільними. Випадковий пошук даних на диску займає 1/200-ту секунду. Повільна версія запиту завершилася, зробивши щось на зразок 600 000 таких запитів, і пройшло близько години. (Це зробило більше пошукових запитів, ніж це, але кешування застало деякі з них.) На відміну від швидкої версії знали, що вона повинна прочитати все і передавати дані на швидкості 70 кб / с. Він потрапив через 11 ГБ таблиці за 3 хвилини.