Mevcut bir bölümlenmemiş tablo nasıl bölümlenir


22

Veri içeren bir tablom var:

dbo.Test (col1,col2,col3....) ON [PRIMARY]

Bu şekilde bölümlenebilmek için bu tabloyu değiştirmem gerekiyor:

dbo.Test(col1,col2,col3....) ON Ps_Date(Col2)

Masayı düşürmeden ve yeniden yaratmadan bunu nasıl başarabilirim?

Yanıtlar:


23

Bir tabloyu bölümlemek için aşağıdaki kısa adımları takip edebilirsiniz:

  • ilk önce bir bölümleme işlevi oluşturun ve bölüm düzeni oluşturun
  • Bundan sonra bir tablo bölümlendirebilirsiniz.
  • Masanızda kümelenmiş bir dizin varsa, onu doğru bölüme bırakıp yeniden oluşturmanız gerekir, aksi takdirde kullanabilirsiniz. DROP_EXISTING kümelenmiş dizini yeniden oluşturmak için yan tümce .
  • Tablonuz kümelenmiş bir dizine sahip değilse, o zaman bölüm şemasını kullanarak sadece sağ bölümde bir tane oluşturabilirsiniz.
  • Ayrıca Enterprise Edition , ONLINE=ONuygulamanızın aksama süresini en aza indirmek için CREATE INDEX deyiminin seçeneğini kullanma esnekliğine de sahiptir . ONLINE seçeneğini kullanarak dizin yeniden oluşturulurken performansın düşeceğini göreceksiniz.

Bölümlemeyi otomatikleştirmek için, SQL Server Partition Management (SQL Server Bölüm Yönetimi) yardımcı programını veya kodeksi üzerinde de bulunan SQL Server Partitioned Table Framework'ü kullanabilirsiniz.

Bazı iyi kaynaklar:


53

Tablonuzda kümelenmiş bir dizin olup olmadığını belirtmezsiniz, o nedenle tüm seçenekleri gözden geçirelim.

Bu örnek bölüm işlevini, bölüm düzenini ve tabloyu kullanacağım:

CREATE PARTITION FUNCTION pf1(INT) AS RANGE LEFT FOR VALUES(10,20,30,40);
GO
CREATE PARTITION SCHEME ps1 AS PARTITION pf1 ALL TO ([PRIMARY])
GO
CREATE TABLE dbo.pt(pc INT NOT NULL, id INT NOT NULL) ON [PRIMARY];
GO

1. Tablonuz bir kısıtlama tarafından yaratılmamış kümelenmiş bir dizine sahiptir.

Bu en kolay durum. Sadece CREATE INDEXifadeyi kullanabilirsiniz .DROP_EXISTINGTabloyu bölüm düzenine taşımak için deyimi yan tümce .

Bu kümelenmiş dizinin oluşturulduğunu varsayalım:

CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(Id) ON [PRIMARY];

Bu tabloyu bölümlemek için, kümelenmiş dizin anahtarın bir parçası olarak bölüm sütununu (bizim durumumuzda pt) içermiştir. Bu ifade, kümelenmiş dizini bölüm sütununu içerecek şekilde değiştirir ve aynı anda bölümler:

CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(pc, Id) WITH(DROP_EXISTING = ON)ON ps1(pc) ;

DROP_ExistingFıkra otomatik olarak yeni bir tane oluşturmadan önce varolan endeksi kaldırır. Bu, DROP INDEXkümelenmemiş dizinlerin yalnızca bir kez yeniden oluşturulmasına neden olduğu için ayrı olarak tercih edilir .

2. tablo parçası olan bir kümelenmiş bir dizin PRIMARY KEYveya UNIQUEkısıtlama ve anahtarın bir parçası olarak bölme sütun içerir

Bu hala kolay ve öncekine çok benzer.

Bu PRIMARY KEYkısıtlamanın masada oluşturulduğunu varsayalım :

ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY CLUSTERED (pc, Id) ON [PRIMARY];

Şimdi sadece 1 de kullandığımız yeniden yaratma betiğini çalıştırabilirsiniz:

CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(pc, Id) WITH(DROP_EXISTING = ON)ON ps1(pc) ;

3. tablo bölüm sütunu içermez fakat bir parçası olarak oluşturulan bir kümelenmiş bir dizin PRIMARY KEYveya UNIQUEkısıtlama

Zor şans. Gerçekliğin ardından a PRIMARY KEYveya UNIQUEkısıtlamanın tanımını değiştiremezsiniz . Tek seçeneğiniz kısıtlamayı bırakmak ve sonra bunu bölüm sütunu dahil yeniden oluşturmak veya bölüm sütununu içeren kısıtlamadan bağımsız olarak kümelenmiş bir dizin oluşturmaktır. İkinci durumda, kısıtlamayı NONCLUSTEREDbölüm sütununu eklemeden yeniden oluşturabilirsiniz . Çünkü şimdi bu kısıtlama hizalı değil (yani destek endeksi bölümlenmemiş), diskin nereye yerleştirileceğini belirtmeniz gerekiyor.

Masanın şöyle bir birincil anahtarı olduğunu varsayalım:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY CLUSTERED (Id) ON [PRIMARY];

Bu tabloyu bölümlemek için önce kısıtlamayı bırakmanız gerekir:

ALTER TABLE dbo.pt DROP CONSTRAINT ptc;

Ardından bölümlenmiş kümelenmiş dizini oluşturmanız gerekir:

CREATE UNIQUE CLUSTERED INDEX ptci ON dbo.pt(pc, Id) ON ps1(pc) ;

PRIMARY KEYHizasız hizalamayı yeniden oluşturmayı seçerseniz bunu şöyle yapabilirsiniz:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY NONCLUSTERED (Id) ON [PRIMARY];

4. Tablonuz kümelenmiş bir dizine sahip değil

Bu durumda, çoğu durumda bölümlemeyi oluşturmak için yalnızca kümelenmiş bir dizin oluşturulması önerilir. Bunun için daha önce görülen create index deyimini kullanabilirsiniz:

CREATE UNIQUE CLUSTERED INDEX ptci ON dbo.pt(pc, Id) ON ps1(pc) ;

Ancak, kümelenmiş bir dizin oluşturmamak için iyi bir nedeniniz varsa, aşağıdaki iki adımlı yaklaşımı ortadan kaldırabilirsiniz. Ne yazık ki bu değişikliği yapmanın doğrudan bir yolu yok.

Tablonuzun kümelenmiş bir dizini olmadığını varsayalım. Tabloyu bölümlemek için önce bir CLUSTERED UNIQUEkısıtlama oluşturmanız gerekir . (Ayrıca bir CLUSTERED PRIMARY KEYkısıtlama kullanabilirsiniz ). Benzersiz bir sütun birleşimi varsa, bu basit bir adımdır:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc UNIQUE CLUSTERED(pc,id);

Kısıtlama oluşturulduktan sonra tekrar bırakabilir ve aynı zamanda tabloyu yeni bölüm şemasına "taşıyabilirsin":

ALTER TABLE dbo.pt DROP CONSTRAINT ptc WITH(MOVE TO ps1(pc));

Eşsiz bir sütun kombinasyonunuz yoksa, şansınız kalmaz. Bu durumda tek seçeneğiniz yeni bir sütun eklemek ve onu benzersiz değerlerle doldurmak. Eğer masa oldukça küçükse, böyle bir şey yapabilirsiniz:

ALTER TABLE dbo.pt ADD tmp_id INT IDENTITY(1,1);

Ancak, tüm satırlar değerleninceye kadar bu özel bir masa kilidi alacaktır. Masa boyutuna bağlı olarak bu bir süre olabilir. Bu sütun oluşturulduktan sonra, ilk UNIQUEkısıtlamayı oluşturmak için yukarıdaki iki adımı izleyin ve ardından hemen tekrar bırakın. Daha sonra sütunu tekrar bırakabilirsiniz. Tüm bu adımlar oldukça müdahalecidir, bu nedenle muhtemelen sadece tablo üzerinde kümelenmiş bir dizin oluşturmaktan daha iyidir. Bu bile benzersiz olmak zorunda değildir.


Enterprise Edition’ınız varsa, WITH(ONLINE=ON)maddeyi yukarıdaki ifadelerin çoğunda kullanabilirsiniz . Bu, tablonuzu diğer bağlantılara açık tutacaktır. Ancak, bu süre zarfında performans etkisi olacaktır.


1
Mükemmel, Sabastian! Sadece mükemmel düz! Sadece yukarıdaki # 3'e eklemek için ... SWITCH'i içeri veya dışarı kullanmak istiyorsanız, tüm indekslerin hizalanması gerekir. Kümelenmemiş, hizalanmamış bir PK yapmak, ilk önce dizini bırakma adımları atmadığınız sürece SWITCH yapmanıza, SWITCH yapmanıza (hangi yönde olursa olsun) ve dizini yeniden oluşturmanıza izin vermez. Bu, çoğu kez silmeyle eşdeğerden daha hızlıdır ve SWITCH kullanmanız gerekmiyorsa, elbette sorun olmaz.
Jeff Moden
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.