it-swarm.com.de

Deaktivieren Sie alle Indizes in einer SQL Server-Datenbank und aktivieren Sie sie erneut

Ich führe ein DTS aus, um Aufgaben in meiner Datenbank vorzuformen, in denen ich zunächst all in der Datenbank deaktivieren und sie wieder aktivieren muss, wenn DTS seine Arbeit beendet.

Gibt es eine Möglichkeit, alle Indizes in der gesamten Datenbank zu deaktivieren und sie anschließend wieder zu aktivieren?

Ich kann eins nach dem anderen deaktivieren/aktivieren, kann mir jemand helfen, alle auf einmal als Schritt in der DTS zu deaktivieren/aktivieren.

19
Eran Meir

Hier ist ein Skript, das ALTER-Anweisungen für alle nicht gruppierten Indizes in Ihrer Datenbank ausgibt. Sie können dies leicht ändern, um REBUILD-Skripts und Skripts für Cluster-Indizes auszugeben 

select 'ALTER INDEX ' + I.name + ' ON ' + T.name + ' DISABLE' 
from sys.indexes I
inner join sys.tables T on I.object_id = T.object_id
where I.type_desc = 'NONCLUSTERED'
and I.name is not null
32

Dies funktioniert für SQL Server 2008 und neuere Versionen. Es erlaubt verschiedene Schemata und Namen, die Leerzeichen, Bindestriche und andere Sonderzeichen enthalten, die in Anführungszeichen gesetzt werden müssen. Was ist die Verwendung der eckigen Klammern [] in SQL-Anweisungen?

Diese Skripts geben Code in die Ergebnisregisterkarte aus. Sie müssen in die Abfrage-Registerkarte kopieren/einfügen und sie ausführen.

Skript deaktivieren

SELECT 'ALTER INDEX ' + QUOTENAME(I.name) + ' ON ' +  QUOTENAME(SCHEMA_NAME(T.schema_id))+'.'+ QUOTENAME(T.name) + ' DISABLE' 
FROM sys.indexes I
INNER JOIN sys.tables T ON I.object_id = T.object_id
WHERE I.type_desc = 'NONCLUSTERED'
AND I.name IS NOT NULL
AND I.is_disabled = 0

Skript aktivieren (Neuaufbau)

SELECT 'ALTER INDEX ' + QUOTENAME(I.name) + ' ON ' +  QUOTENAME(SCHEMA_NAME(T.schema_id))+'.'+ QUOTENAME(T.name) + ' REBUILD' 
FROM sys.indexes I
INNER JOIN sys.tables T ON I.object_id = T.object_id
WHERE I.type_desc = 'NONCLUSTERED'
AND I.name IS NOT NULL
AND I.is_disabled = 1

Dies basiert auf einer anderen Antwort hier.

25
Juan Font

Mit scrip können Sie Indizes deaktivieren 

ALTER INDEX ALL ON [TableName]
DISABLE;

Führen Sie Ihre Masseneinfügung in die Tabelle aus und führen Sie sie dann unterhalb des Skripts aus.

ALTER INDEX ALL ON [TableName]
REBUILD;
17
Rahul Garg

Um einen Index zu aktivieren, müssen Sie ihn neu erstellen. Dieses Skript erstellt alle deaktivierten Indizes neu.

DECLARE @my_sql2 NVARCHAR(200);

DECLARE cur_rebuild CURSOR FOR 
   SELECT 'ALTER INDEX ' +  i.name + ' ON ' + t.name + ' REBUILD' FROM sys.indexes i JOIN sys.tables t ON i.object_id = t.object_id WHERE i.is_disabled = 1 ORDER BY t.name, i.name;
OPEN cur_rebuild;
FETCH NEXT FROM cur_rebuild INTO @my_sql2;
WHILE @@FETCH_STATUS = 0
   BEGIN
      EXECUTE sp_executesql  @my_sql2;
      FETCH NEXT FROM cur_rebuild INTO @my_sql2;
   END;
CLOSE cur_rebuild;
DEALLOCATE cur_rebuild;
GO
5
Duncan

Sie müssen ein Skript ausführen, das die Metadaten für die Tabelle und den Index auswählt. Dann können Sie Folgendes tun:

ALTER INDEX indexname ON tablename DISABLE; 

Später können Sie ein ähnliches Skript ausführen, um es neu zu erstellen:

ALTER INDEX indexname ON tablename REBUILD; 

Sie können diese nacheinander ausführen oder in einer NVARCHAR (MAX) -Variablen sammeln und als einen einzelnen Stapel ausführen. Beispielcode finden Sie unter dieser früheren Frage:

Alle nicht gruppierten Indizes deaktivieren

3
RLF

Das Deaktivieren von Indizes ist eine gute Idee, wenn große Datenmengen geladen werden sollen. Das große Problem sind jedoch Clustered-Indizes. Wenn Sie einen Clustered-Index deaktivieren, haben Sie die gesamte Tabelle deaktiviert.

Mehrere Optionen bieten sich an, und keine davon ist einfach.

1) Durchlaufen Sie die Systemansichten (sys.indexes), extrahieren Sie den Namen der Tabelle und des Index, generieren und führen Sie dynamisches SQL aus, um den Index zu deaktivieren. Machen Sie eine "Rückgängig" -Routine, um sie wieder zu aktivieren. (Seien Sie vorsichtig - war es ein eindeutiger Index oder eine eindeutige Einschränkung?) Dies funktioniert leider nur, wenn Sie keine Clustered-Indizes verwenden. Viel Glück damit.

2) Wie für 1, jedoch alle Clustered-Indizes überspringen. Stellen Sie beim Laden von Daten sicher, dass sie in sequentieller Reihenfolge (Clustered-Index) geladen werden. Andernfalls werden schlechte Ladezeiten und fragmentierte Tabellen angezeigt. (Wenn Sie Datenanbieter wie meine sind, viel Glück auch mit diesem.)

3) Erstellen Sie in Ihrer Datenbank Tabellen mit Definitionen der Indizes für Ihre Ladetabellen. Erstellen Sie eine Routine, die alle durchläuft und drop alle Indizes (zuletzt Clustered-Indizes). Dies ist schnell, wenn Sie die Tabellen zuerst abschneiden. Laden Sie Ihre Daten, durchlaufen Sie die Indizes und erstellen Sie die Indizes von Grund auf neu (gruppiert). Verwenden Sie die Tabellenpartitionierung, um den Rest des Systems weniger schrecklich zu machen (führen Sie beispielsweise alle oben genannten Schritte in den Ladetabellen aus, und verschieben Sie dann die geladenen Daten mithilfe der Partitionsumschaltung in Ihre Live-Tabellen). Ich habe nicht wenig Zeit gebraucht, um ein solches System aufzubauen, aber es kann und wird funktionieren.

2
Philip Kelley

Verwenden Sie dieses Skript, um alle Indizes zu deaktivieren

-- Disable All Indices
DECLARE @Script NVARCHAR(MAX)
DECLARE curIndices CURSOR FAST_FORWARD READ_ONLY FOR
    SELECT 'ALTER INDEX ' + QUOTENAME(indices.name) + ' ON ' + QUOTENAME(SCHEMA_NAME(tableNames.schema_id))+'.'+ QUOTENAME(tableNames.name) + ' DISABLE'
    FROM
        sys.indexes indices  INNER JOIN 
        sys.tables tableNames ON indices.object_id = tableNames.object_id
    WHERE 
        indices.type_desc = 'NONCLUSTERED' AND 
        indices.name IS NOT NULL AND
        indices.is_disabled = 0;
OPEN curIndices
FETCH NEXT FROM curIndices INTO @Script
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @Script
    EXECUTE sp_executesql @Script 

    FETCH NEXT FROM curIndices INTO @Script
END
CLOSE curIndices
DEALLOCATE curIndices

Verwenden Sie dieses Skript, um alle Indizes neu zu erstellen (aktivieren)

-- Rebuild All Indices
DECLARE @Script NVARCHAR(MAX)
DECLARE curIndices CURSOR FAST_FORWARD READ_ONLY FOR
    SELECT 'ALTER INDEX ' + QUOTENAME(indices.name) + ' ON ' + QUOTENAME(SCHEMA_NAME(tableNames.schema_id))+'.'+ QUOTENAME(tableNames.name) + ' REBUILD'
    FROM
        sys.indexes indices  INNER JOIN 
        sys.tables tableNames ON indices.object_id = tableNames.object_id
    WHERE 
        indices.type_desc = 'NONCLUSTERED' AND 
        indices.name IS NOT NULL AND
        indices.is_disabled = 1;
OPEN curIndices
FETCH NEXT FROM curIndices INTO @Script
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @Script
    EXECUTE sp_executesql @Script 

    FETCH NEXT FROM curIndices INTO @Script
END
CLOSE curIndices
DEALLOCATE curIndices
0
Fred