Нет индексов на маленьких таблицах?

«Мы должны забыть о небольшой эффективности, скажем, примерно в 97% случаев: преждевременная оптимизация - корень всех зол». (Дональд Кнут). Мои таблицы SQL вряд ли будут содержать более нескольких тысяч строк каждая (и это большие!). Помощник по настройке ядра СУБД SQL Server отклоняет объем данных как несущественный. Так что я не должен даже думать о том, чтобы помещать явные индексы в эти таблицы. Правильный?


person onedaywhen    schedule 31.10.2008    source источник


Ответы (13)


Значение индексов выражается в увеличении скорости чтения. Например, если вы выполняете много операций SELECT на основе диапазона дат в столбце даты, имеет смысл поместить индекс в этот столбец. И, конечно же, обычно вы добавляете индексы в любой столбец, к которому собираетесь присоединиться, с любой значительной частотой. Повышение эффективности также связано с отношением размера ваших типичных наборов записей к количеству записей (т. Е. Получение 20/2000 записей дает больше преимуществ от индексации, чем получение 90/100 записей). Поиск в неиндексированном столбце - это, по сути, линейный поиск.

Стоимость индексов зависит от записи, потому что каждый INSERT также требует внутренней вставки в каждый индекс столбца.

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

Идентификация и сравнительный анализ нескольких наиболее частых операций вашего приложения с индексами в столбцах JOIN / WHERE и без них занимает очень мало времени, я предлагаю вам это сделать. Также разумно отслеживать ваше производственное приложение и определять самые дорогие и наиболее частые запросы, а также сосредотачивать усилия по оптимизации на пересечении этих двух наборов запросов (что может означать индексы или что-то совершенно другое, например, выделение большего или меньшего количества памяти для запросить или присоединиться к кешам).

person joelhardi    schedule 31.10.2008
comment
Если таблицы достаточно малы, имеют кластерный индекс (обычно первичный ключ) и никакой покрывающий индекс не удовлетворяет запросу, оптимизатор SQL Server не будет использовать индекс. Вместо этого будет сканироваться таблица. Это связано с тем, что поиск книг в кластеризованном индексе обходится дорого. - person Mitch Wheat; 31.10.2008
comment
Это имеет смысл ... данные строк хранятся в конечных узлах кластеризованного индекса, поэтому SQL выполняет поиск на тех же страницах с поиском индекса или просмотром таблицы (грубо говоря). Я отвечал в более общем плане - некластеризованные индексы для столбцов, отличных от PK, которые позволяют выполнять поиск в b-дереве вместо линейного сканирования. - person joelhardi; 31.10.2008
comment
Это зависит от того, сколько логических чтений произведено операторами, использующими эти таблицы. Если запросы к таблицам выполняются неправильно, например, для аргументации путем вызова функции, которая считывает встроенную таблицу, вы можете получить множество операций чтения даже для небольшой таблицы. Я бы посмотрел на планы запросов и использовал набор статистики ввода-вывода, чтобы проверить, сколько операций чтения с диска создается для небольшой таблицы. Если их немного и эти части запроса имеют низкую стоимость в плане запроса, то, вероятно, в индексах мало смысла. Итог - это зависит от того, как запрашиваются таблицы. - person Jonathan Shields; 05.08.2016
comment
Даже если у вас много чтений в небольшой таблице, индекс может не понадобиться, потому что база данных будет его кэшировать. - person deFreitas; 12.09.2018
comment
Я думаю, что ответ состоит в том, чтобы запустить объяснение запроса, а затем протестировать его на производстве, используя канареечный выпуск, переключение функций и т.д. - person deFreitas; 12.09.2018

Мудрые слова Кнута неприменимы к созданию (или нет) индексов, поскольку, добавляя индексы, вы не ничего оптимизируете напрямую: вы предоставляете индекс, который оптимизатор СУБД может используйте для оптимизации некоторых запросов. Фактически, вы могли бы лучше возразить, что решение не индексировать небольшую таблицу является преждевременной оптимизацией, поскольку тем самым вы ограничиваете возможности оптимизатора СУБД!

Разные СУБД будут иметь разные рекомендации по выбору индексации столбцов на основе различных факторов, включая размер таблицы, и именно их следует учитывать.

Что является примером преждевременной оптимизации в базах данных: «денормализация для повышения производительности» до того, как какой-либо сравнительный анализ покажет, что нормализованная база данных действительно имеет какие-либо проблемы с производительностью.

person Tony Andrews    schedule 31.10.2008

Столбцы первичного ключа будут проиндексированы для ограничения уникальности. Я бы по-прежнему индексировал все столбцы внешнего ключа. Оптимизатор может проигнорировать ваш индекс, если он не имеет значения.

Если у вас мало данных, дополнительные затраты на вставку / обновление также не должны быть значительными.

person WW.    schedule 31.10.2008

Совершенно неверно. 100% неверно. Не помещайте миллион бессмысленных индексов, но вам действительно нужен первичный ключ (в большинстве случаев), и вы хотите, чтобы он был правильно КЛАСТЕРИРОВАН.

Вот почему:

SELECT * FROM MySmallTable <-- No worries... Index won't help

SELECT
    *
FROM
    MyBigTable INNER JOIN MySmallTable ON... <-- Ahh, now I'm glad I have my index.

Вот хорошее правило.

«Поскольку у меня есть ТАБЛИЦА, я, вероятно, захочу запросить ее когда-нибудь ... Если я собираюсь запросить ее, я, вероятно, сделаю это последовательным способом ...» ‹- - Вот как вы должны индексировать таблицу.

РЕДАКТИРОВАТЬ: Я добавляю эту строку: Если у вас есть конкретный пример, я покажу вам, как его индексировать и какую экономию вы получите от этого. Пожалуйста, предоставьте таблицу и пример того, как вы планируете использовать эту таблицу.

person Timothy Khouri    schedule 31.10.2008

По-разному. Таблица справочная?

Существуют таблицы из тысячи строк, в которых отсутствует индекс, и результаты сканирования таблиц могут иметь значение между довольно простой операцией, задерживающей пользователя на 5 минут вместо 5 секунд. Я видел именно эту проблему, используя СУБД, отличную от SQL Server.

Как правило, если таблица является справочной, обновления в ней будут происходить относительно редко. Это означает, что снижение производительности при обновлении индекса также будет относительно редким. Если оптимизатор пропускает индекс, снижение производительности оптимизатора будет незначительным. Пространство, необходимое для хранения индекса, также будет незначительным.

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

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

Вот общее практическое правило: придерживайтесь поведения СУБД по умолчанию, если только вы не найдете причины не делать этого. Все остальное - это преждевременная забота об оптимизации с вашей стороны.

person Walter Mitty    schedule 31.10.2008

Я предлагаю вам следовать обычным правилам индексирования, что примерно означает «создавать индексы для тех столбцов, которые вы используете в своих запросах».

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

Но, если база данных растет (какие базы данных иногда имеют тенденцию к этому), вам не нужно помнить о добавлении индексов в эту старую базу данных, о которой вы, вероятно, уже забыли. Возможно, он даже был установлен у одного из ваших клиентов, и вы не можете его изменить!

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

person Thomas Padron-McCarthy    schedule 31.10.2008

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

person Mitch Wheat    schedule 31.10.2008

Поместите индексы ТОЛЬКО, если вам нужно :)
Бывают случаи, когда размещение индексов может действительно снизить производительность, в зависимости от того, для чего используется таблица ...
Другими словами, вы могли бы подумать о том, чтобы разместить индексы на таблицы, когда это необходимо, как это определено профилированием приложения.

person Aleris    schedule 31.10.2008
comment
индексы замедляют операции записи (поскольку индексы также должны обновляться, и эти обновления также должны быть сброшены на диск в какой-то момент), плюс индекс также занимает место на диске и в памяти, а позже может вызвать больше подкачки, которая в свою очередь может вызвать снижение производительности. - person Tyrael; 22.05.2013

Индексы часто создаются неявно при использовании ограничений UNIQUE. В таком случае я бы не стал избегать их использования!

person Greg Hewgill    schedule 31.10.2008
comment
Если вы добавляете ограничение UNIQUE, база данных всегда (а не только часто) будет добавлять индекс. - person Sten Vesterli; 31.10.2008

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

Но иногда они могут дать огромный импульс, как я обрисовал здесь .

person Michael K. Campbell    schedule 04.11.2008

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

Итак, да, явных индексов можно избежать, если есть небольшой набор данных, над которым нужно работать.

person Nrj    schedule 31.10.2008

Даже если у вас есть индекс, SQL Server может даже не использовать его, в зависимости от статистики для этой таблицы. И если вы планируете добавить индекс для отчета, который будет запускаться не более пары раз в год, имейте в виду, что штрафы INSERT / UPDATE за добавление индекса будут действовать ВСЕ ВРЕМЯ. Перед добавлением индекса спросите себя, стоит ли оно снижения производительности.

person Maxam    schedule 31.10.2008

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

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

person Jé Queue    schedule 30.10.2009