@Pierre 303 уже сказал это, но я скажу это снова. НУЖНО использовать индексы для комбинаций столбцов. Объединенный индекс (a, b)
только для запросов медленнее, a
чем индекс a
один, и намного лучше, если ваш запрос объединяет оба столбца. Некоторые базы данных могут объединять индексы в таблице a
и b
до нее, но это не так хорошо, как объединенный индекс. Когда вы создаете комбинированный индекс, вы должны поместить столбец, который наиболее вероятно будет найден первым в комбинированном индексе.
Если ваша база данных поддерживает это, DO ставит индексы для функций, которые отображаются в запросах, а не в столбцах. (Если вы вызываете функцию для столбца, индексы для этого столбца бесполезны.)
Если вы используете базу данных с настоящими временными таблицами, которые вы можете создавать и уничтожать на лету (например, PostgreSQL, MySQL, но не Oracle), то ДОЛЖНЫ создавать индексы для временных таблиц.
Если вы используете базу данных, которая позволяет это (например, Oracle), СДЕЛАЙТЕ блокировку хороших планов запросов. Оптимизаторы запросов со временем изменят планы запросов. Они обычно улучшают план. Но иногда они делают это значительно хуже. Как правило, вы не заметите улучшения плана - запрос не был узким местом. Но один плохой план может разрушить загруженный сайт.
НЕ имеют индексов для таблиц, для которых вы собираетесь выполнить большую загрузку данных. Гораздо, намного быстрее отбрасывать индексы, загружать данные, а затем перестраивать индексы, чем поддерживать их при загрузке таблицы.
НЕ ИСПОЛЬЗУЙТЕ индексы для запросов, которые должны обращаться к более чем небольшой части большой таблицы. (Как мало зависит от аппаратного обеспечения. 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 минуты.