Подтвердить что ты не робот

Могут ли индексы фактически снизить производительность SELECT?

Возможный дубликат:
Ухудшение производительности запроса после добавления индекса

после прочтения некоторых сведений об индексах на SQL Server и их преимуществ по производительности для выборок и недостатков для обновлений/вставок, мне было интересно, могут ли плохо используемые индексы также повредить производительность для выборок. Какие условия должны быть выполнены, чтобы снизить производительность запроса чистого выбора? Существуют ли такие ситуации?

Спасибо!

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

4b9b3361

Ответ 1

Да, хотя и очень немного - настолько немного, что было бы оправдано также ответить "Нет".

Если у вас есть индекс, который может быть рассмотрен для запроса, но не используется, оптимизатор будет тратить время на размышления о том, как и как его использовать (в редких случаях с ДЕЙСТВИТЕЛЬНО сложными индексами и представлениями и чаще, когда подсказки производительности индекса неверны, вы можете в конечном итоге выбрать субоптимальный план запроса).

В некоторых случаях:

  • таблица без индексов
  • таблица с плохо выбранным индексом, который отбрасывается
  • таблица, где существуют два индекса, и по какой-либо причине (например, устаревшая статистика) наличие второго индекса делает его оптимизатором, в то время как было бы удобнее использовать первый.

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

Если индекс вредит вам - где ВСЕ индексы причиняют вам боль, - это вставлять, удалять и обновлять. Тогда любой индекс, не используемый в запросе обновления, но затронутый тем же, потребует записи в самом индексе.

Итак, вы захотите иметь индексы, но не меньше, чем можете, не жертвуя успехами SELECT. Фактически, вы можете решить против индексирования для редко используемого запроса SELECT, чтобы избежать необходимости постоянного обновления индекса всеми другими запросами UPDATE.

Edit: после прочтения ответа Heinzi, я также хотел бы добавить, что на большинстве серверов БД есть инструменты обслуживания, которые анализируют таблицы и индексы (а иногда и запрашивают счетчики производительности) и правильно обновляют подсказки, о которых говорил Хайнци. Поэтому также важно периодически "поддерживать" базу данных, чтобы оптимизатор предоставлял самую свежую информацию о том, какие индексы выбрать.

Обновление (MySQL)

Существует очень отличный инструмент анализа MySQL, который может реально предложить улучшения существующего индексации (удалить неиспользуемые ключи, добавить полезные ключи): common_schema. Это действительно стоит посмотреть.

Ответ 2

Да, но это очень маловероятно, и это не должно влиять на ваше решение использовать индексы.

Иногда анализатор запросов SQL Server выбирает план выполнения, который не является оптимальным. Поскольку количество возможных планов выполнения намного больше, чем может показаться на первый взгляд (простое соединение таблиц n уже создает n! возможные планы выполнения), SQL Server должен сделать обоснованное предположение. Это в природе догадок, что они иногда ошибаются.

Это редкое явление, но я видел, как это происходило пару раз за последние годы. В этом случае (и только в этом случае) лучший план был бы выбран, если бы индекс не был там. Однако удаление индекса не является правильным способом решения этой проблемы, поскольку индекс обычно существует по какой-либо причине. Правильный способ - добавить подсказку к этому запросу (и только к этому запросу), чтобы помочь оптимизатору выбрать правильный план.

Ответ 3

Да, индексы могут повредить производительность для SELECT. Важно понимать, как работают двигатели баз данных. Данные хранятся на диске (дисках) на "страницах". Индексы позволяют получить доступ к определенной странице, которая имеет определенное значение в одном или нескольких столбцах в таблице.

Это замечательно, если вы ищете конкретные значения.

Однако рассмотрите запрос, который должен смотреть на каждую строку в таблице. Если вы проходите через стол, вы читаете страницы в порядке и - критически - вы получаете каждую строку на странице с одним чтением. Количество чтений - это количество страниц в таблице. Кроме того, кеш-страница может оптимизировать чтение с помощью ожидающих чтения, а страницы, которые больше не используются, просто перезаписываются.

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

Как правило, компонент оптимизатора SQL-сервера отлично справляется с различиями между этими двумя ситуациями. Одним из ключевых показателей является избирательность запроса. Сколько строк возвращает запрос (что оптимизатор смотрит на количество страниц)? Если количество строк примерно такое же, как количество страниц, оптимизатор рассмотрит полное сканирование таблицы, а не сканирование индекса.

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

Ответ 4

Я предполагаю, что если вы создадите индексы, которые путают оптимизатор плана запросов, и это приведет к выбору неэффективного индекса для запроса.

Ответ 5

Это потенциально зависит от реализации, но в принципе индексы не должны замедлять SELECT.

Очевидно, что они могут замедлить INSERT и UPDATE.