Bölüm anahtarını güncelleyerek satırları bölümler arasında taşıyabilir miyim?


17

Bunun oldukça basit bir soru olacağını düşünürdüm, ama aslında bunun için bir cevap bulmakta zorlandım.

Soru: Bölümlenmiş bir tablodaki veri satırlarını, bölüm sütununu bölüm sınırını geçecek şekilde güncelleyerek bir bölümden diğerine taşıyabilir misiniz?

Örneğin, bir bölüm anahtarı olan bir tablo varsa:

CREATE TABLE SampleTable
(
    SampleID INT PRIMARY KEY,
    SampleResults VARCHAR(100) NOT NULL,
)

Birincil anahtarla eşleşen bölüm işleviyle:

CREATE PARTITION FUNCTION MyPartitionFunc (INT) AS
RANGE LEFT FOR VALUES (10000, 20000);

SampleID değerini 1'den (örneğin) 500.000'e değiştirerek bir satırı ilk bölümden üçüncü bölüme taşıyabilir miyim?

Not: İkisini de bölümlemeyi desteklediğinden, hem sql server 2005 hem de 2008 olarak etiketliyorum. Farklı mı ele alıyorlar?

Yanıtlar:


14

Test edilecek 2005 sunucum yok. Ancak 2008'in beklendiği gibi üstesinden geldiği görülmektedir:

USE [Test]
GO
CREATE TABLE [IDRanges](
    [ID] [int] NOT NULL
)
GO

CREATE PARTITION FUNCTION IDRange1 (int)
AS RANGE LEFT FOR VALUES (10) ;
GO
--Add one record to each partition
INSERT INTO IDRanges ([ID]) VALUES (17)
INSERT INTO IDRanges ([ID]) VALUES (7)
GO
--Verify records in partition
SELECT $PARTITION.IDRange1([ID]) AS Partition, COUNT(*) AS [COUNT] 
FROM IDRanges
GROUP BY $PARTITION.IDRange1([ID]) 
ORDER BY Partition ;
GO
--Move row between partitions
UPDATE IDRanges
SET [ID] = 8 WHERE [ID] = 17
GO
--Verify records in partition
SELECT $PARTITION.IDRange1([ID]) AS Partition, COUNT(*) AS [COUNT] 
FROM IDRanges
GROUP BY $PARTITION.IDRange1([ID]) 
ORDER BY Partition ;

Güncellemeden önce her bölümde bir kayıt ve daha sonra ilk bölümde bulunan her iki kaydı da görmelisiniz.


1
bu güzel yapılmış bir cevap!
Marian

Bu, SQL Server 2005'te de açıkladığınız gibi çalışır
Ben Brocka 21

-1 Bu senaryoyu test etmez. $PARTITIONyalnızca girdiye göre bölüm numarasını hesaplar; aslında sıranın fiziksel olarak nerede yaşadığını test etmez.
Jon Seigel

9

Bunu test etmek için deneyin aslında tabloyu bölümlere ayırması gerekir. Bkz. Http://www.kodyaz.com/articles/how-to-partition-table-non-partitioned-table-sql-server-2008.aspx

Bölümleme işlevini sorgulamak size bölümleme işlevinin ne söylediğini gösterir. Verilerin nerede depolandığını söylemez. Bölümleme işlevi ayarlayabilir ve burada zaten gösterildiği gibi bir tabloyu bölümlere ayırmadan çalıştırabilirsiniz.

Tabloyu bölümlemek için, dosya gruplarına işlev sonuçları atamak için dosya grupları ve bölümleme işlevini kullanan bir bölümleme şeması da oluşturmanız gerekir. Ardından, bu bölümleme şemasını kullanan tabloya kümelenmiş bir anahtar koymanız gerekir.

Bölümlemeyi ayarlama

Komut satırı SQL konusunda uzman değilim. Pfg1 (pf1 dosyasıyla) ve pfg2 (pf2 dosyasıyla) dosya gruplarını ayarlamak için SSMS arabirimini kullandım. Sonra bölümleme işlevi ve şemasını ilan ettim:

CREATE PARTITION FUNCTION IDRange1 (int)
AS RANGE LEFT FOR VALUES (10) ;
GO

CREATE PARTITION SCHEME ps_IDRange1
AS PARTITION IDRange1
TO (pfg1, pfg2)
GO

Tablo ve kümelenmiş dizin oluşturma

CREATE TABLE [IDRanges](
    [ID] [int] NOT NULL
)
GO

CREATE CLUSTERED INDEX PK_IDRanges
ON dbo.IDRanges(id) ON ps_IDRange1 (ID)
GO

Bunu yaptıktan sonra, sys.partitions'ı (2005 var) sorguladığınızda, tablonun artık tablo için tek yerine iki bölüm olduğunu görürsünüz. Bu, bu tablo için bölümlemeyi tamamen uyguladığımızı gösterir.

select * from sys.partitions where object_id = object_id('IDRanges')
partition_id object_id dizin_kimliği partition_number hobt_id satırlar
-------------------- ----------- ----------- -------- -------- -------------------- --------------------
72057597780295680 770674389 1 1 72057597780295680 0
72057597780361216 770674389 1 2 72057597780361216 0

Şimdi iki bölümümüz var (her biri için bir satır sayısı ile), bir deney yapabiliriz.

Satırları ekle

INSERT INTO IDRanges ([ID]) VALUES (17)
INSERT INTO IDRanges ([ID]) VALUES (7)

Ne olduğunu görmek için sys.partitions'ı kontrol edin.

select * from sys.partitions where object_id = object_id('IDRanges')
partition_id object_id dizin_kimliği partition_number hobt_id satırlar
-------------------- ----------- ----------- -------- -------- -------------------- --------------------
72057597780295680 770674389 1 1 72057597780295680 1
72057597780361216 770674389 1 2 72057597780361216 1

Evet. Her bölümde bir satır.

Bir satırı taşıyın.

UPDATE IDRanges
SET [ID] = 8 WHERE [ID] = 17

Bölümleri kontrol edin

select * from sys.partitions where object_id = object_id('IDRanges')
partition_id object_id dizin_kimliği partition_number hobt_id satırlar
-------------------- ----------- ----------- -------- -------- -------------------- --------------------
72057597780295680 770674389 1 1 72057597780295680 2
72057597780361216 770674389 1 2 72057597780361216 0

İlk bölüm artık 1 yerine iki satıra sahiptir ve ikinci bölüm iki yerine sıfır satıra sahiptir.

Bence bu, bölümlenmiş bir tabloda kümelenmiş anahtarın değiştirilmesi sonucunda satırın otomatik olarak taşındığını doğrular.


1
Senaryoyu gerçekten test eden bu soruya ilk cevap için +1. DBA.SE'ye Hoşgeldiniz!
Jon Seigel

-1 Lütfen beni bir tabloyu 'tamamen' bölümlemek için gereksinimlerinizi destekleyen MSDN belgelerine yönlendirebilir misiniz? Özellikle ayrı dosya grupları ve kümelenmiş bir dizin için gereklilik mi?
Kenneth

-2

Cevabın doğru olduğunu düşünmüyorum. Değeri kullandığınızda

 $PARTITION.IDRange1([ID]) AS Partition

kaydın şu anda olduğu yerde değil, bölümün ne olması gerektiğini yeniden hesaplıyorsunuz.

Kullanmalısın:

select * from sys.partitions where object_id = object_id('IDRanges')

Sql 2005'teki testlerimde değer değişiyor, ancak kayıt aynı bölümde kalıyor. Bu, muhtemelen bir bölümün belirli bir aralıkta olmasını bekleyen çok iş parçacıklı bir modda çalışacağı için istatistiklerle ve optimize ediciyle karıştırır. Ayrıca, yalnızca ilgili bölümü sorgulamak için bölüm eliminasyonunu kullanmaya çalıştığında da tamamen yanlış olacaktır. Her kaydı silmeniz ve yeniden eklemeniz gerektiğini düşünüyorum.


2
$partition Burada arama yapmak , kabul edilen cevabın doğru olduğunu gösterir. Güncellendikten sonra kaydın aynı bölümde kaldığını nasıl onaylıyorsunuz?
Nick Chammas

İlk nokta doğrudur, ancak satırın hareket etmediği sonucu yanlıştır - muhtemelen yürütülen testte bir sorun vardır.
Jon Seigel
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.