ฉันสามารถย้ายแถวระหว่างพาร์ติชั่นโดยอัพเดตพาร์ติชั่นคีย์ได้ไหม?


17

ฉันคิดว่านี่เป็นคำถามที่ค่อนข้างง่าย แต่จริง ๆ แล้วฉันมีช่วงเวลาที่ยากลำบากในการหาคำตอบสำหรับเรื่องนี้

คำถาม: คุณสามารถย้ายแถวของข้อมูลภายในตารางที่แบ่งพาร์ติชันจากพาร์ติชันหนึ่งไปยังอีกพาร์ติชันโดยเพียงแค่การปรับปรุงคอลัมน์พาร์ติชันเพื่อที่จะข้ามขอบเขตพาร์ติชัน?

ตัวอย่างเช่นถ้าฉันมีตารางที่มีพาร์ติชันคีย์:

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

ด้วยฟังก์ชั่นพาร์ติชันที่จับคู่กับคีย์หลัก:

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

ฉันสามารถย้ายแถวจากพาร์ติชันแรกไปยังพาร์ติชันที่สามได้โดยเปลี่ยน SampleID จาก 1 เป็น 500,000 (พูด) 500,000 หรือไม่

หมายเหตุ: ฉันติดแท็กเป็นทั้งเซิร์ฟเวอร์ sql 2005 และ 2008 เนื่องจากทั้งสองสนับสนุนการแบ่งพาร์ติชัน พวกเขาจัดการกับมันแตกต่างกันหรือไม่?

คำตอบ:


14

ฉันไม่มีเซิร์ฟเวอร์ 2005 ที่จะทดสอบด้วย อย่างไรก็ตามในปี 2008 ดูเหมือนจะจัดการสิ่งนี้ตามที่คาดไว้:

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 ;

คุณควรเห็นหนึ่งเร็กคอร์ดในแต่ละพาร์ติชันก่อนการอัพเดตและทั้งสองเร็กคอร์ดในพาร์ติชันแรกหลังจากนั้น


1
นั่นเป็นคำตอบที่ทำได้ดีมาก!
แมเรียน

สิ่งนี้ดำเนินการตามที่คุณอธิบายใน SQL Server 2005 เช่นกัน
Ben Brocka

-1 สิ่งนี้ไม่ได้ทดสอบภาพจำลอง $PARTITIONคำนวณหมายเลขพาร์ติชันตามอินพุตเท่านั้น มันไม่ได้ทดสอบว่าแถวนั้นอยู่ทางไหน
Jon Seigel

9

ในการทดสอบสิ่งนี้การทดสอบจำเป็นต้องแบ่งพาร์ติชันตาราง ดูhttp://www.kodyaz.com/articles/how-to-partition-table-non-partitioned-table-sql-server-2008.aspx

การสอบถามฟังก์ชันการแบ่งพาร์ติชั่นจะบอกให้คุณทราบว่าฟังก์ชันการแบ่งพาร์ติชันนั้นเป็นอย่างไร ไม่ได้บอกว่าเก็บข้อมูลไว้ที่ไหน คุณสามารถตั้งค่าฟังก์ชั่นการแบ่งพาร์ติชันและรันโดยไม่ต้องแบ่งพาร์ติชั่นตารางตามที่แสดงไว้แล้วที่นี่

ในการแบ่งพาร์ติชันตารางคุณต้องสร้างกลุ่มไฟล์และรูปแบบการแบ่งพาร์ติชันที่ใช้ฟังก์ชันการแบ่งพาร์ติชันเพื่อกำหนดผลลัพธ์ของฟังก์ชั่นให้กับกลุ่มไฟล์ จากนั้นคุณต้องใส่คีย์คลัสเตอร์ในตารางที่ใช้โครงร่างการแบ่งพาร์ติชันนั้น

ตั้งค่าการแบ่งพาร์ติชัน

ฉันไม่มีความเชี่ยวชาญใน SQL บรรทัดคำสั่ง ฉันใช้อินเตอร์เฟส SSMS เพื่อตั้งค่ากลุ่มไฟล์ pfg1 (พร้อมไฟล์ pf1) และ pfg2 (พร้อมไฟล์ pf2) จากนั้นฉันก็ประกาศฟังก์ชั่นการแบ่งและรูปแบบ:

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

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

สร้างตารางและดัชนีคลัสเตอร์

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

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

หลังจากคุณทำเช่นนี้เมื่อคุณเคียวรี sys.partitions (ฉันมี 2005) คุณจะเห็นว่าตอนนี้ตารางมีสองพาร์ติชันแทนที่จะเป็นพาร์ติชั่นเดียวสำหรับตาราง สิ่งนี้บ่งชี้ว่าเราได้ทำการแบ่งพาร์ติชั่นสำหรับตารางนี้อย่างสมบูรณ์

select * from sys.partitions where object_id = object_id('IDRanges')
partition_id object_id index_id partition_number แถว hobt_id
-------------------- ----------- ----------- -------- -------- -------------------- --------------------
72057597780295680 770674389 1 1 72057597780295680 0
72057597780361216 770674389 1 2 72057597780361216 0

ตอนนี้เรามีสองพาร์ติชั่น (ด้วยการนับแถวสำหรับแต่ละ) เราสามารถทำการทดลอง

แทรกแถว

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

ตรวจสอบ sys.partitions เพื่อดูว่าเกิดอะไรขึ้น

select * from sys.partitions where object_id = object_id('IDRanges')
partition_id object_id index_id partition_number แถว hobt_id
-------------------- ----------- ----------- -------- -------- -------------------- --------------------
72057597780295680 770674389 1 1 72057597780295680 1
72057597780361216 770674389 1 2 72057597780361216 1

อ๋อ หนึ่งแถวในแต่ละพาร์ติชัน

ย้ายแถว

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

ตรวจสอบพาร์ติชั่น

select * from sys.partitions where object_id = object_id('IDRanges')
partition_id object_id index_id partition_number แถว hobt_id
-------------------- ----------- ----------- -------- -------- -------------------- --------------------
72057597780295680 770674389 1 1 72057597780295680 2
72057597780361216 770674389 1 2 72057597780361216 0

ตอนนี้พาร์ติชันแรกมีสองแถวแทน 1 และพาร์ติชันที่สองมีศูนย์แถวแทนสอง

ฉันคิดว่านี่เป็นการยืนยันว่าแถวถูกย้ายโดยอัตโนมัติเนื่องจากการแก้ไขคีย์คลัสเตอร์ในตารางที่แบ่งพาร์ติชัน


1
+1 สำหรับคำตอบแรกสำหรับคำถามนี้ที่ทดสอบสถานการณ์จริง ยินดีต้อนรับสู่ DBA.SE!
Jon Seigel

-1 คุณช่วยชี้ฉันไปที่เอกสาร MSDN ที่สนับสนุนความต้องการของคุณในการแบ่งพาร์ติชันแบบเต็มตารางได้หรือไม่? ความจำเป็นเฉพาะสำหรับกลุ่มไฟล์แยกกันและดัชนีคลัสเตอร์หรือไม่?
Kenneth

-2

ฉันไม่คิดว่าคำตอบนั้นถูกต้อง เมื่อคุณใช้ค่า

 $PARTITION.IDRange1([ID]) AS Partition

คุณเพียงคำนวณสิ่งที่พาร์ติชันควรไม่ใช่ตำแหน่งที่บันทึกในปัจจุบัน

คุณควรใช้:

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

ในการทดสอบของฉันใน sql 2005 ค่าเปลี่ยนแปลง แต่บันทึกอยู่ในพาร์ติชันเดียวกัน นี่อาจจะยุ่งกับสถิติและเครื่องมือเพิ่มประสิทธิภาพเนื่องจากมันจะทำงานในโหมดมัลติเธรดที่คาดว่าพาร์ติชันจะอยู่ในช่วงที่ระบุ มันจะผิดอย่างสมบูรณ์เมื่อพยายามใช้การกำจัดพาร์ติชันเพื่อสอบถามพาร์ติชันที่เกี่ยวข้องเท่านั้น ฉันคิดว่าคุณต้องลบและแทรกแต่ละระเบียนใหม่เพื่อให้พวกเขาย้าย


2
การค้นหา$partition ตรงนี้แนะนำว่าคำตอบที่ยอมรับนั้นถูกต้อง คุณจะยืนยันได้อย่างไรว่าระเบียนยังคงอยู่ในพาร์ติชันเดียวกันหลังจากที่ได้รับการปรับปรุงแล้ว?
Nick Chammas

จุดแรกเป็นจริง แต่ข้อสรุปว่าแถวไม่ย้ายเป็นเท็จ - สันนิษฐานว่ามีบางอย่างผิดปกติกับการทดสอบที่ทำงาน
Jon Seigel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.