2009-04-01 20 views
6

İki sütun üzerinde kümelenmiş bir dizin içeren bir tablom var - tablonun birincil anahtarı. aşağıdaki gibi tanımlanmaktadır:Kümelenmiş dizini (PK) SQL 2005'te değiştirmenin en iyi yolu

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] 

bu kümelenmiş dizin PK kaldırıp şöyle gibi kümelenmiş bir dizin ekleme ve ayrıca aşağıda gösterilen olmayan bir kümelenmiş dizini kullanarak birincil anahtar kısıtlaması eklemek istiyorum.

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] 

Sadece PK, ardından yeni kümelenmiş dizin ekleyin ve sonra kümelenmemiş birincil anahtar indeksi eklemek endeksi kümelenmiş býrakacaktým ama mevcut kümelenmiş dizin bırakarak tablo verilerini neden olacağı öğrenilen Yeniden düşünülmelidir (burada cevabın What happens when I drop a clustered primary key in SQL 2005 numaralı cevabına bakın). Tablo 1 TB'yi çalıyor, bu yüzden gereksiz yeniden sıralamalardan kaçınmak istiyorum.

Sorum şu: Mevcut yapıdan istenen yapıya gitmenin en iyi yolu nedir?

DÜZENLEME: Sadece açıklığa kavuşturmak istiyorum. Tablo 1TB ve maalesef geçici bir tablo oluşturmak için alanım yok. Temp tablosu oluşturmadan bunu yapmanın bir yolu varsa lütfen bana bildirin.

cevap

8

yeni kümelenmiş bir dizin ekle boyutu 1 TB kadar almak ve büyük olasılıkla içinde satırlar var, ben Kümelenmiş indeksi çok daha fazla yağ yapma DEĞİL tavsiye ederim!

Her şeyden önce, kümelenmiş dizinin bırakılması ve yeniden oluşturulması tüm verilerinizi en az bir kez karıştırır - bu yalnızca yaşları alır. İkinci olarak, oluşturmaya çalıştığınız büyük bileşik kümelenmiş dizin, kümelenmemiş tüm dizinlerin boyutunu önemli ölçüde artıracaktır (bunlar, her bir yaprak düğümünde, yer işareti aramaları için kümelenmiş dizin değerini içerdiklerinden).

Soru şudur: neden bunu yapmaya çalışıyorsunuz? Sorgularınızı potansiyel olarak kapsamak için, bu sütunlarla birlikte kümelenmemiş başka bir dizin eklemez misiniz? Neden bu kümelenmiş dizin olmalı? Bu konuda hiçbir avantaj görmüyorum ....

İndeksleme ve özellikle kümelenmiş dizin tartışması hakkında daha fazla bilgi için, bkz. SQL Server dizinlerindeki Kimberly Tripp's blog - çok yararlı!

Marc

4
  1. Yeni bir tablo oluşturun: masanın

  2. DAN yenitablo SELECT'te * INTO

    INSERT :

    CREATE TABLE newtable (colA INT, colB INT) 
    
    • takın yeni tabloya eski tablodan tüm değerler

    • Eski bırakın tablo:

      ALTER TABLE:

      DROP TABLE tablo

    • EXEC sp_rename 'yenitablo', 'tablo'

    • endeksler kurmak eski tabloya yeni bir tablo yeniden adlandırma Tablo ADD CONSTRAINT PK_Table BİRİNCİL ANAHTAR NONCLUSTERED ( ColA,= KAPALI OLAN 0 colB ) (STATISTICS_NORECOMPUTE, IGNORE_DUP_KEY = KAPALI, ALLOW_ROW_LOCKS = ON [PRIMARY]

+0

Bu bir seçenek değil. 1.5TB RAID üzerinde 1TB tablom var. –

+0

SQL Server, yeniden sıralama ve taşıma için alan gerekecek. Boş alanınız yoksa, tablonuzu geçici bir depoda oluşturmak için DROP INDEX'te MOVE TO seçeneğini kullanabilir ve ardından RAID'inizde yeniden oluşturabilirsiniz. – Quassnoi

+0

Satırları, satırları yığın halinde aktarabilir ve bunları gittikçe kaynaktan silebilirsiniz. Bu muhtemelen çok yavaş bir süreç olurdu. –

11

Bu sorunuza tam bir cevap değil, ama emin olun AÇIK ALLOW_PAGE_LOCKS = AÇIK) Tablodaki başka bir indeks varsa, ilk önce bunları düşürürsünüz. Aksi halde, kümelenmiş dizini kaldırdığınızda SQL Server'ın hepsini yeniden derlemesi ve sonra yeniden kümelenmiş bir dizin eklediğinizde bunları yeniden oluşturması gerekecektir.Her zamanki adımlar şunlardır: tablo ise

  1. Sürücülerden tüm kümelenmemiş dizinleri
  2. Kaldır kümelenmiş dizin
  3. geri Ekle olmayan tüm kümelenmiş dizin
+0

Eh, bu benim ilk planımdı, fakat kümelenmiş dizini kaldırmanın 2. adımı tüm verilerin taşınmasına neden oluyor. Gereksiz bir veri hareketini önlemek için adım 2 ve 3'ü bir araya getirmeyi umuyordum. –

-1

Kümelenmiş dizin aslında tablo içinde kendini o depolanan verilerin fiziksel düzeni değişmez. SQL 6.5 beri bu şekilde olmamıştı.

Sayfalardaki veriler doğru sırada depolanır. Sayfalar herhangi bir fiziksel sırayla diskte saklanabilir.

+0

bu doğru mu? Verilerin fiziksel düzeninin kümelenme anahtarı tarafından belirlendiği izleniminin altındaydım. –

+0

Sayfalardaki veriler doğru sırada saklanır. Sayfalar herhangi bir fiziksel sırayla diskte saklanabilir. – mrdenny

+2

Yanıtınızı bu ayrımı içerecek şekilde güncellemek isteyebilirsiniz. –