2017-01-31 4 views
2

Что происходит на стороне сервера SQL Server, когда я удаляю индекс из одной из моих таблиц?Что происходит, когда некластеризованный индекс удаляется?

Подробности: У меня есть база данных, запущенная в производство.

В этой базе данных у меня есть запрос, который создает взаимоблокировки на регулярной основе. Я нашел запрос, создающий тупик, запустил его на моем компьютере, показывая его план выполнения. SQL Server Management Studio предлагает добавить индекс в одну конкретную таблицу.

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

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

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

Могу ли я просто использовать команду DROP Index без особых проблем? Мне не нужно перестраивать или что-то еще?

+0

Вы можете сбросить ненужные индексы, но вы также можете добавить подсказку запроса, чтобы [принудительно использовать SQL-сервер для использования определенного индекса] (https://blog.sqlauthority.com/2009/02/08/sql-server-introduction -to-force-index-query-hints-index-hint-part2 /) –

+1

Напоминал меня об этом недавнем [@TrumpDBA] (https://twitter.com/TrumpDBA/status/826154547299151872) твит –

ответ

6

Некластеризованный индекс - это вторичная структура данных - он не «интегрирован» в основную структуру данных кластеризованного индекса или кучи.

Таким образом, удаление одного из них должно быть относительно быстрым и безболезненным, так как все системы необходимо выполнить, это удалить метаданные об индексе и пометить страницы индекса как нераспределенные.

Не должно быть необходимости «перестраивать» или делать что-либо еще.

1

Вы можете запустить этот запрос, чтобы получить знать, используются ли индексы таблицы или не

SELECT TOP 50 
    o.name AS ObjectName 
, i.name AS IndexName 
, i.index_id AS IndexID 
, dm_ius.user_seeks AS UserSeek 
, dm_ius.user_scans AS UserScans 
, dm_ius.user_lookups AS UserLookups 
, dm_ius.user_updates AS UserUpdates 
, p.TableRows 
, 'DROP INDEX ' + QUOTENAME(i.name) 
+ ' ON ' + QUOTENAME(s.name) + '.' 
+ QUOTENAME(OBJECT_NAME(dm_ius.OBJECT_ID)) AS 'drop statement' 
FROM sys.dm_db_index_usage_stats dm_ius 
INNER JOIN sys.indexes i ON i.index_id = dm_ius.index_id 
AND dm_ius.OBJECT_ID = i.OBJECT_ID 
INNER JOIN sys.objects o ON dm_ius.OBJECT_ID = o.OBJECT_ID 
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id 
INNER JOIN (SELECT SUM(p.rows) TableRows, p.index_id, p.OBJECT_ID 
FROM sys.partitions p GROUP BY p.index_id, p.OBJECT_ID) p 
ON p.index_id = dm_ius.index_id AND dm_ius.OBJECT_ID = p.OBJECT_ID 
WHERE OBJECTPROPERTY(dm_ius.OBJECT_ID,'IsUserTable') = 1 and o.name='your_table_name' 
AND dm_ius.database_id = DB_ID() 
AND i.type_desc = 'nonclustered' 
AND i.is_primary_key = 0 
AND i.is_unique_constraint = 0 
ORDER BY (dm_ius.user_seeks + dm_ius.user_scans + dm_ius.user_lookups) ASC 
GO 

Затем идут с индексом DROP заявление, если какой-либо из них не используются. Перед тем как сбросить, убедитесь, что сервер был UP в течение длительного времени, поэтому индексы получили возможность привыкнуть.

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

+0

Спасибо за очень полезный запрос! –