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

Когда создавать новый индекс SQL Server?

Очевидно, что (methinks), создание индекса в столбце BIT не требуется. Однако, если у вас есть столбец, который вам нужно искать, в котором каждое значение, вероятно, уникально, например BlogPost или StreetAddress или что-то еще, то индекс кажется подходящим (опять же, methinks).

Но какое обрезание? Что, если вы ожидаете 10 000 строк, и у вас будет около 20 уникальных значений. Должен ли создаваться индекс?

Спасибо заранее.

4b9b3361

Ответ 1

Лучший ответ на этот вопрос - профилировать ваши запросы и посмотреть, улучшает ли индекс ваши запросы. Трудность в ответе на это состоит в том, что почти невозможно обобщить поведение оптимизатора запросов.

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

Это не сложное и быстрое правило, так как существует множество факторов, которые могут изменить 10% -ный номер, включая использование кластерных или других типов индексов, размер строк, если некоторые столбцы не встроены, структура запроса, и т.д.

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

См. статью MSDN в Таблицы и доступ к индексу.

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

Ответ 2

Джеймс ударил ноготь по голове. Я просто добавлю, что даже бит столбца может извлечь выгоду из индекса в зависимости от того, как вы используете таблицу. Например, если вам нужно подсчитать количество строк, которые имеют 1 много раз в течение дня, индекс может быть полезен. Индексы не всегда касаются поиска одной записи - они также могут использоваться для агрегаций.

Ответ 3

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

Пример: у меня была таблица с полем State, которая принимала только значения "A", "N" и "R" (для активных, новых и отставных). Обычно вы подходите к условию, 95% были "R", 4% - "A", а некоторые были "N". SELECT WHERE state = 'N' будет сканирование таблицы, независимо от того, что.

НО - новый тип индекса, называемый Filtered Index, который, наконец, обрабатывает это условие. Это также удобно, если вы хотите исключить записи со значениями NULL.

Ответ 4

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

Все столбцы внешнего ключа должны быть проиндексированы.

В противном случае я бы не помещал индекс в нормальных условиях на такой столбец.

Ответ 5

создание индекса в столбце BIT не требуется.

Вы были бы удивлены.

Мне пришлось создать индекс, содержащий бит столбца для запроса типа:

SELECT foo.Name FROM foo WHERE foo.Active = 1

В таблице было около 300 000 строк.

Ответ 6

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

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

Ответ 7

Вы также должны внимательно изучить свои индексы, если вы начинаете испытывать взаимоблокировки среди запросов, как правило, между SELECT и INSERT/UPDATE. Низко выбранный индекс может способствовать взаимоблокировкам, так как не может иметь индекс вообще. См. эту базу знаний для дополнительной информации. Обычно добавление индекса или изменение его включенных столбцов поможет разрешить такие взаимоблокировки. Обязательно изучите план запроса затронутых запросов.

Ответ 8

одним из лучших способов является использование представлений mvp в SQL Server i sugest не перезагружать сервер в течение одной недели, а затем запускать этот запрос:

USE master; 
Go
SELECT d.database_id,
  d.object_id,
  d.index_handle,
  d.equality_columns,
  d.inequality_columns,
  d.included_columns,
  d.statement AS fully_qualified_object,
  gs.*
FROM   sys.dm_db_missing_index_groups g
JOIN   sys.dm_db_missing_index_group_stats gs ON   gs.group_handle = g.index_group_handle
JOIN   sys.dm_db_missing_index_details d ON   g.index_handle = d.index_handle

Go

SELECT mig.index_group_handle,
  mid.index_handle,
  migs.avg_total_user_cost AS AvgTotalUserCostThatCouldbeReduced,
  migs.avg_user_impact AS AvgPercentageBenefit,
  'CREATE INDEX missing_index_' + CONVERT (varchar, mig.index_group_handle)
  + '_' + CONVERT (varchar, mid.index_handle)
  + ' ON ' + mid.statement
  + ' (' + ISNULL (mid.equality_columns,'')
  + CASE
         WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns
         IS NOT NULL THEN ','
         ELSE ''
    END
    + ISNULL (mid.inequality_columns, '')
  + ')'
  + ISNULL (' INCLUDE (' + mid.included_columns + ')', '') AS  create_index_statement
FROM sys.dm_db_missing_index_groups mig 
INNER JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle =  mig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details mid ON mig.index_handle =  mid.index_handle
Order By migs.avg_user_impact Desc

затем проверьте свои таблицы и создайте индекс requerd.

Ответ 9

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

Из Используете ли вы SQL файлы с отсутствующим индексом SQL?

SELECT
  migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) AS improvement_measure,
  'CREATE INDEX [missing_index_' + CONVERT (varchar, mig.index_group_handle) + '_' + CONVERT (varchar, mid.index_handle)
  + '_' + LEFT (PARSENAME(mid.statement, 1), 32) + ']'
  + ' ON ' + mid.statement
  + ' (' + ISNULL (mid.equality_columns,'')
    + CASE WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL THEN ',' ELSE '' END
    + ISNULL (mid.inequality_columns, '')
  + ')'
  + ISNULL (' INCLUDE (' + mid.included_columns + ')', '') AS create_index_statement,
  migs.*, mid.database_id, mid.[object_id]
FROM sys.dm_db_missing_index_groups mig
INNER JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle
WHERE migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) > 10
ORDER BY migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) DESC