Как решить, когда использовать индекс в столбце таблицы

Когда я должен использовать индекс в таблице?

  1. Из скольких строк индекс имеет смысл?
  2. Если у меня есть таблица с постоянными строками, только что отредактированные столбцы прихода (не в предложении «где»), имеет смысл индексировать, даже если в таблице всего около 15 строк? РЕДАКТИРОВАТЬ: Может ли в таком случае выбор/чтение без индекса быть более эффективным, чем чтение индекса?

РЕДАКТИРОВАТЬ: Сейчас я работаю с firebird 2.5, но большую часть времени я использую SQL Server 2005/2008.


person Fanda    schedule 16.08.2012    source источник
comment
Какая система баз данных и какая версия?? SQL — это всего лишь язык структурированных запросов — язык, используемый многими системами баз данных, но не являющийся продуктом базы данных... такие функции часто зависят от поставщика, поэтому мы действительно нужно знать, какую систему баз данных вы используете....   -  person marc_s    schedule 16.08.2012
comment
Я думаю, что это общий вопрос, не так много зависит от системы sql. Но теперь уточняется. Спасибо.   -  person Fanda    schedule 16.08.2012
comment
Как и когда применять индексирование, сильно зависит от реальной системы, поэтому я хотел знать, с чем вы работаете.   -  person marc_s    schedule 16.08.2012
comment
Хорошо, вы, вероятно, правы. :-)   -  person Fanda    schedule 16.08.2012


Ответы (5)


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

  • выберите хороший ключ кластеризации — не GUID, не VARCHAR(250) или что-то в этом роде — хороший ключ кластеризации узкий, уникальный, стабильный, постоянно увеличивающийся - что-то вроде INT IDENTITY идеально. Делает это вашим кластерным первичным ключом -> дает вам ваш первый индекс в таблице

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

И это все на данный момент.

Затем: запустите свою систему — наблюдайте и измерьте — установите базовый уровень. Приложение достаточно быстрое? Если да -> вы закончили - идите домой и наслаждайтесь свободным временем.

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

Если у вас есть улучшение -> оставьте этот индекс на месте, и это измерение станет вашим новым базовым уровнем. Промойте и повторяйте, пока вы (и ваши пользователи) не будете довольны производительностью приложения (а затем затем отправляйтесь домой и наслаждайтесь свободным временем).

Чрезмерная индексация в SQL Server может быть хуже, чем отсутствие индексов. Не начинайте со слишком большого количества индексов! Установите только хорошие кластеризованные PK и некластеризованные индексы внешнего ключа — вот и все — затем наблюдайте, измеряйте, оптимизируйте и повторяйте этот цикл.

person marc_s    schedule 16.08.2012
comment
+1 за упоминание делать одно изменение за раз между базовыми тестами. - person Furbeenator; 04.04.2013

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

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

Если вы используете SQL Server, вы можете запустить трассировку с помощью профилировщика SQL Server, чтобы помочь вам

РЕДАКТИРОВАТЬ:

Может ли быть в таком случае неиндексный выбор/чтение более эффективным, чем индексное чтение?

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

person Diego    schedule 16.08.2012

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

Некоторые упоминали о взятии базового уровня, использовании какой-либо утилиты трассировки для измерения производительности и т. д. Если вас устраивает установленная производительность, продолжайте. Если нет, проанализируйте план выполнения, физическую модель данных (доступные индексы), пересчитайте статистику и посмотрите, поможет ли это оптимизатору выбрать лучший план выполнения. Убедитесь, что СУБД может (разрешено) использовать доступную оперативную память. Попробуйте свести к минимуму дисковый ввод-вывод и так далее.

В случае с Firebird 2.5 недавно добавленный Firebird Trace API — это находка. Теперь вы, наконец, можете получить трассировку практически в реальном времени того, что выполняется в базе данных, с помощью счетчиков производительности (план выполнения, время выполнения, статистика ввода-вывода...). И сторонний продукт под названием FB TraceManager от Upscene Productions превращает использование Trace API в удовольствие.

person tsteinmaurer    schedule 16.08.2012

Что касается второй части вашего вопроса, если в таблице всего 15 строк, весьма вероятно, что независимо от того, сколько у вас индексов, таблица всегда будет сканироваться, потому что она такая маленькая.

person Tim Harkin    schedule 16.08.2012

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

-- Missing Indexes for current database by Index Advantage  (Query 57) (Missing Indexes)
SELECT DISTINCT CONVERT(decimal(18,2), user_seeks * avg_total_user_cost * (avg_user_impact * 0.01)) AS [index_advantage], 
migs.last_user_seek, mid.[statement] AS [Database.Schema.Table],
mid.equality_columns, mid.inequality_columns, mid.included_columns,
migs.unique_compiles, migs.user_seeks, migs.avg_total_user_cost, migs.avg_user_impact,
OBJECT_NAME(mid.[object_id]) AS [Table Name], p.rows AS [Table Rows]
FROM sys.dm_db_missing_index_group_stats AS migs WITH (NOLOCK)
INNER JOIN sys.dm_db_missing_index_groups AS mig WITH (NOLOCK)
ON migs.group_handle = mig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details AS mid WITH (NOLOCK)
ON mig.index_handle = mid.index_handle
INNER JOIN sys.partitions AS p WITH (NOLOCK)
ON p.[object_id] = mid.[object_id]
WHERE mid.database_id = DB_ID() 
ORDER BY index_advantage DESC OPTION (RECOMPILE);

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

person Luis Teijon    schedule 02.06.2017