6 Stimmen

Beste Möglichkeit, den gruppierten Index (PK) in SQL 2005 zu ändern

Ich habe eine Tabelle, die einen gruppierten Index auf zwei Spalten hat - den Primärschlüssel für die Tabelle. Es ist wie folgt definiert:

ALTER TABLE Table ADD CONSTRAINT [PK_Table] PRIMARY KEY CLUSTERED
(
  [ColA] ASC,
  [ColB] ASC
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]

Ich möchte diesen gruppierten Index PK entfernen und einen gruppierten Index wie folgt hinzufügen und eine Primärschlüssel-Beschränkung unter Verwendung eines nicht gruppierten Indexes hinzufügen, wie unten gezeigt.

CREATE CLUSTERED INDEX [IX_Clustered] ON [Table]
(
  [ColC] ASC,
  [ColA] ASC,
  [ColD] ASC,
  [ColE] ASC,
  [ColF] ASC,
  [ColG] ASC
)WITH (PAD_INDEX  = ON, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF,     DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, FILLFACTOR = 90, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = OFF) ON [PRIMARY]

ALTER TABLE Table ADD CONSTRAINT
  PK_Table PRIMARY KEY NONCLUSTERED
  (
    ColA,
    ColB
  ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

Ich wollte einfach den PK gruppierten Index löschen, dann den neuen gruppierten Index hinzufügen und dann den nicht gruppierten Primärschlüsselindex hinzufügen, aber ich habe erfahren, dass das Löschen des vorhandenen gruppierten Indexes dazu führen würde, dass die Tabellendaten neu geordnet werden (siehe Antwort hier Was passiert, wenn ich einen gruppierten Primärschlüssel in SQL 2005 lösche), was meiner Meinung nach nicht notwendig sein sollte. Die Tabelle ist 1 TB groß, daher möchte ich wirklich jede unnötige Neuordnung vermeiden.

Meine Frage ist, wie man am besten von der vorhandenen Struktur zur gewünschten Struktur gelangt?

EDIT: Möchte nur klarstellen. Die Tabelle ist 1 TB groß und ich habe leider keinen Platz, um eine temporäre Tabelle zu erstellen. Falls es einen Weg gibt, dies ohne Erstellen einer Temp-Tabelle zu tun, lassen Sie es mich bitte wissen.

12voto

Tom H Punkte 45699

Dies ist keine vollständige Antwort auf Ihre Frage, aber stellen Sie sicher, dass Sie zuerst alle anderen Indizes in der Tabelle löschen, wenn Sie diese haben. Andernfalls muss SQL Server sie alle neu erstellen, wenn Sie den gruppierten Index entfernen, und sie dann erneut neu erstellen, wenn Sie einen neuen gruppierten Index hinzufügen. Die üblichen Schritte sind:

  1. Alle nicht gruppierten Indizes entfernen
  2. Gruppierten Index entfernen
  3. Neuen gruppierten Index hinzufügen
  4. Alle nicht gruppierten Indizes wieder hinzufügen

0 Stimmen

Nun, das war mein ursprünglicher Plan, aber der zweite Schritt, den gruppierten Index zu entfernen, führt dazu, dass alle Daten verschoben werden. Ich hoffte, Schritt 2 und 3 irgendwie zu verschmelzen, um eine unnötige Datenverschiebung zu vermeiden.

8voto

marc_s Punkte 701497

Wenn Ihre Tabelle bis zu 1 TB groß wird und wahrscheinlich VIELE Zeilen enthält, würde ich dringend davon abraten, den gruppierten Index so viel breiter zu machen!

Zunächst einmal wird das Löschen und Neu Erstellen des gruppierten Index alle Ihre Daten mindestens einmal durcheinander bringen - das allein wird ewig dauern.

Zweitens wird der große zusammengesetzte gruppierte Index, den Sie erstellen möchten, die Größe aller Ihrer nicht gruppierten Indizes erheblich erhöhen (da sie den gesamten gruppierten Indexwert auf jedem Blattknoten enthalten, für die Lesevorgänge mit Lesezeichen).

Die Frage lautet eher: Warum versuchen Sie das zu tun?? Könnten Sie nicht einfach einen weiteren nicht gruppierten Index mit diesen Spalten hinzufügen, um potenziell Ihre Abfragen abzudecken? Warum muss das der gruppierte Index sein?? Ich sehe keinen Vorteil darin....

Weitere Informationen zu Indizierung und insbesondere zur Diskussion über den gruppierten Index finden Sie auf Kimberly Tripps Blog über SQL Server-Indizes - sehr hilfreich!

Marc

4voto

Quassnoi Punkte 396418
  1. Eine neue Tabelle erstellen:

    CREATE TABLE newtable (colA INT, colB INT)
    • Alle Werte aus der alten Tabelle in die neue Tabelle einfügen:

      INSERT INTO newtable SELECT * FROM table

    • Die alte Tabelle löschen:

      DROP TABLE table

    • Die neue Tabelle in die alte Tabelle umbenennen

      EXEC sp_rename 'newtable', 'table'

    • Die Indexe erstellen:

      ALTER TABLE Table ADD CONSTRAINT PK_Table PRIMARY KEY NONCLUSTERED ( ColA, ColB ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

0 Stimmen

Das ist keine Option. Ich habe eine 1-TB-Tabelle auf einem 1,5-TB-RAID.

0 Stimmen

SQL Server benötigt Platz sowohl für das Umsortieren als auch für das Verschieben. Wenn Ihnen der Platz ausgeht, können Sie die MOVE TO-Option im DROP INDEX verwenden, um Ihre Tabelle in einem temporären Speicher zu erstellen, und sie dann erneut auf Ihrem RAID zu erstellen.

0 Stimmen

Sie könnten Zeilen portionsweise übertragen, wobei Sie sie aus der Quelle löschen, während Sie vorgehen. Das wäre wahrscheinlich ein sehr langsamer Prozess.

-3voto

mrdenny Punkte 4802

Gruppierte Indizes ändern tatsächlich nicht die physische Reihenfolge der im Tabellenspeicher selbst gespeicherten Daten. Das ist seit SQL 6.5 nicht mehr so.

Die Daten auf den Seiten werden in der richtigen Reihenfolge gespeichert. Die Seiten können auf der Festplatte in beliebiger physischer Reihenfolge gespeichert werden.

0 Stimmen

Ist das wahr? Ich hatte den Eindruck, dass die physische Reihenfolge der Daten durch den Clustering-Key bestimmt wurde.

0 Stimmen

Die Daten auf den Seiten werden in der richtigen Reihenfolge gespeichert. Die Seiten können auf der Festplatte in beliebiger physischer Reihenfolge gespeichert werden.

2 Stimmen

Du solltest deine Antwort möglicherweise aktualisieren, um diese Unterscheidung einzubeziehen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X