Как совместить потенциальные показатели - PullRequest
0 голосов
/ 10 октября 2019

Некоторый код «отсутствующего индекса» (см. Ниже), который я получил при поиске в Интернете, перечисляет множество потенциальных отсутствующих индексов для конкретной таблицы. Буквально говорится, что мне нужно 30 индексов. У меня уже было 8 до запуска кода. Большинство экспертов утверждают, что таблица должна составлять в среднем 5. Могу ли я объединить большинство из этих отсутствующих индексов, чтобы она покрывала большинство потребностей в индексации таблиц?

Например: эти два индекса достаточно похожи, так что кажется, что ониможет быть объединено. Но могут ли они?

CREATE INDEX [NCI_12345] ON [DB].[dbo].[someTable] 
  ([PatSample], [StatusID], [Sub1Sample]) 
  INCLUDE ([PatID], [ProgID], [CQINumber])

CREATE INDEX [NCI_2535_2534] ON [DB].[dbo].[someTable] 
  ([PatSample], [SecRestOnly]) 
  INCLUDE ([CQINumber])

Если я объединю их, это будет выглядеть так:

CREATE INDEX [NCI_12345] ON [DB].[dbo].[someTable] 
  ([PatSample], [StatusID], [Sub1Sample], [SecRestOnly]) 
  INCLUDE ([PatID], [ProgID], [CQINumber])

ПРИМЕЧАНИЕ: я просто взял первое утверждение и добавил к нему [SecRestOnly].

ВОПРОС: Совмещает ли это удовлетворение обеих потребностей индекса? И если нет, то как часто используемая таблица с большим количеством полей будет иметь только 5 индексов?

Вот код, используемый для получения «отсутствующих индексов»:

SELECT
  migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) *
  (migs.user_seeks + migs.user_scans) AS improvement_measure, 
  LEFT (PARSENAME(mid.STATEMENT, 1), 32) as TableName,
  'CREATE INDEX [NCI_' + 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;```

1 Ответ

1 голос
/ 10 октября 2019

Образец, который вы дали, не даст вам желаемого результата. Индекс на ([PatSample], [SecRestOnly]) оптимизирует условия поиска, такие как «PatSample = val1 и SecRestOnly = val2». Объединенный индекс не будет, потому что есть другие сегменты между двумя столбцами в условии поиска. Необходимо помнить, что многосегментный индекс можно использовать только для оптимизации множественного поиска «равенства», когда столбцы в поиске являются начальными последовательными сегментами индекса.

Учитывая это, можно предположить, что если у вас есть один индекс на (col1, col2) и другой на (col1, col2, col3), то первый не нужен.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...