2017-01-31 4 views
2

Was geschieht auf der SQL Server-Engine-Seite, wenn ich einen Index aus einer meiner Tabellen lösche?Was passiert, wenn ein Nonclustered-Index gelöscht wird?

Details: Ich habe eine Datenbank in Produktion.

In dieser Datenbank habe ich eine Abfrage, die regelmäßig Deadlocks erstellt. Ich habe die Abfrage gefunden, die den Deadlock erzeugt, habe ihn auf meinem Computer ausgeführt und den Ausführungsplan angezeigt. SQL Server Management Studio schlägt vor, einen Index für eine bestimmte Tabelle hinzuzufügen.

Der Index ist sinnvoll für mich, aber mein Problem ist, dass ich auf dieser Tabelle bereits 3 Indizes habe und, ehrlich gesagt, kann ich nicht sicher sein, ob sie richtig verwendet werden oder ob sie für eine bestimmte erstellt wurden Rolle.

Ich könnte einfach einen weiteren Index auf dem Tisch hinzufügen, aber ich bin besorgt über die Kosten, die ich jedes Mal zahlen werde, wenn ich Daten auf dem Tisch hinzufüge/aktualisiere/lösche.

Ich habe ein paar Versuche auf meiner Maschine gemacht und es scheint, dass ich mindestens zwei andere Indizes löschen muss, damit die Engine den Index auswählt, den ich heute erstelle (sieht komisch aus). Sobald ich die Engine zwinge, meinen Index zu übernehmen (weil ich alles andere gelöscht habe), läuft die Abfrage zehnmal schneller ab.

Kann ich einfach den DROP Index Befehl ohne viel Problem verwenden? Ich muss nicht umbauen oder irgendetwas?

+0

Sie können nutzlose Indizes löschen, aber Sie können auch einen Abfragehinweis zu [SQL-Server erzwingen, einen bestimmten Index zu verwenden] hinzufügen (https://blog.sqlauthority.com/2009/02/08/sql-server-introduction -to-force-index-abfrage-hinweise-index-hinweis-part2 /) –

+1

Erinnert mich an diese jüngsten [@TrumpDBA] (https://twitter.com/TrumpDBA/status/826154547299151872) Tweet –

Antwort

6

Ein nicht geclusterter Index ist eine sekundäre Datenstruktur - er ist nicht in die Hauptdatenstruktur des Clustered-Indexes oder Heaps integriert.

Daher sollte das Löschen einer Datei eine relativ schnelle und schmerzfreie Erfahrung sein, da das System nur Metadaten über den Index entfernen und die Seiten des Index als nicht zugewiesen markieren muss.

Es sollte nicht nötig sein, "neu aufzubauen" oder irgendetwas anderes zu tun.

1

können Sie diese Abfrage ausführen zu bekommen, ob der Indizes einer Tabelle verwendet oder nicht

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 

Dann mit der DROP INDEX-Anweisung gehen, wenn eine von ihnen nicht verwendet werden. Vergewissern Sie sich vor dem Löschen, dass der Server lange genug in Betrieb war, damit die Indizes verwendet werden können.

Auch drei Indizes auf einer Tabelle sind nicht viele. Überprüfen Sie, ob sie für Ihre Fragen nützlich sind.

+0

Vielen Dank für die sehr nützliche Abfrage! –

Verwandte Themen