เป็นวิธีที่ดีที่สุดในการเก็บถาวรทั้งหมดยกเว้นปีปัจจุบันและแบ่งพาร์ติชันตารางในเวลาเดียวกัน


23

งาน

เก็บถาวรทั้งหมดยกเว้นรอบระยะเวลา 13 เดือนจากกลุ่มของตารางขนาดใหญ่ ข้อมูลที่เก็บถาวรต้องถูกเก็บไว้ในฐานข้อมูลอื่น

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

ตาราง "เก็บถาวร" จะมีประมาณ 1.1 พันล้านแถวตาราง "สด" ประมาณ 400 ล้านแถว เห็นได้ชัดว่าตารางเก็บถาวรจะเพิ่มขึ้นเมื่อเวลาผ่านไป แต่ฉันคาดว่าตารางถ่ายทอดสดจะเพิ่มขึ้นอย่างรวดเร็วด้วยเช่นกัน พูดอย่างน้อย 50% ในอีกไม่กี่ปีข้างหน้า

ฉันคิดเกี่ยวกับฐานข้อมูล Azure ยืด แต่น่าเสียดายที่เราอยู่ที่ 2008 R2 และมีแนวโน้มที่จะอยู่ที่นั่นชั่วครู่

แผนปัจจุบัน

  • สร้างฐานข้อมูลใหม่
  • สร้างตารางใหม่ที่แบ่งพาร์ติชันตามเดือน (โดยใช้วันที่แก้ไข) ในฐานข้อมูลใหม่
  • ย้ายข้อมูล 12-13 เดือนล่าสุดไปยังตารางที่แบ่งพาร์ติชัน
  • ทำการเปลี่ยนชื่อการแลกเปลี่ยนของฐานข้อมูลทั้งสอง
  • ลบข้อมูลที่ย้ายแล้วออกจากฐานข้อมูล "เก็บถาวร" ในขณะนี้
  • แบ่งแต่ละตารางในฐานข้อมูล "เก็บถาวร"
  • ใช้การสลับพาร์ติชันเพื่อเก็บถาวรข้อมูลในอนาคต
    • ฉันรู้ว่าฉันจะต้องสลับข้อมูลที่จะเก็บถาวรคัดลอกตารางนั้นไปยังฐานข้อมูลเก็บถาวรแล้วสลับไปยังตารางเก็บถาวร นี่เป็นที่ยอมรับ

ปัญหา: ฉันกำลังพยายามย้ายข้อมูลไปยังตารางที่แบ่งพาร์ติชันเริ่มต้น (อันที่จริงฉันยังคงทำการพิสูจน์แนวคิดเกี่ยวกับมัน) ฉันพยายามใช้ TF 610 (ตามคู่มือการโหลดข้อมูล ) และINSERT...SELECTคำสั่งเพื่อย้ายข้อมูลในตอนแรกคิดว่ามันจะถูกบันทึกอย่างน้อยที่สุด น่าเสียดายที่ทุกครั้งที่ฉันลองมันจะถูกบันทึกอย่างสมบูรณ์

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

มีอะไรที่ขาดหายไปในแผนทั่วไปหรือไม่และ SSIS เป็นทางออกที่ดีที่สุดของฉันในการย้ายข้อมูลอย่างรวดเร็วและด้วยการใช้บันทึกน้อยที่สุด (ข้อกังวลเกี่ยวกับพื้นที่)?

รหัสการสาธิตที่ไม่มีข้อมูล

-- Existing structure
USE [Audit]
GO

CREATE TABLE [dbo].[AuditTable](
    [Col1] [bigint] NULL,
    [Col2] [int] NULL,
    [Col3] [int] NULL,
    [Col4] [int] NULL,
    [Col5] [int] NULL,
    [Col6] [money] NULL,
    [Modified] [datetime] NULL,
    [ModifiedBy] [varchar](50) NULL,
    [ModifiedType] [char](1) NULL
); 
-- ~1.4 bill rows, ~20% in the last year

CREATE CLUSTERED INDEX [AuditTable_Modified] ON [dbo].[AuditTable]
(   [Modified] ASC   )
GO


-- New DB & Code
USE Audit_New
GO

CREATE PARTITION FUNCTION ThirteenMonthPartFunction (datetime)
AS RANGE RIGHT FOR VALUES ('20150701', '20150801', '20150901', '20151001', '20151101', '20151201', 
                            '20160101', '20160201', '20160301', '20160401', '20160501', '20160601', 
                            '20160701') 

CREATE PARTITION SCHEME ThirteenMonthPartScheme AS PARTITION ThirteenMonthPartFunction
ALL TO ( [PRIMARY] );

CREATE TABLE [dbo].[AuditTable](
    [Col1] [bigint] NULL,
    [Col2] [int] NULL,
    [Col3] [int] NULL,
    [Col4] [int] NULL,
    [Col5] [int] NULL,
    [Col6] [money] NULL,
    [Modified] [datetime] NULL,
    [ModifiedBy] [varchar](50) NULL,
    [ModifiedType] [char](1) NULL
) ON ThirteenMonthPartScheme (Modified)
GO

CREATE CLUSTERED INDEX [AuditTable_Modified] ON [dbo].[AuditTable]
(
    [Modified] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ThirteenMonthPartScheme (Modified)
GO

CREATE NONCLUSTERED INDEX [AuditTable_Col1_Col2_Col3_Col4_Modified] ON [dbo].[AuditTable]
(
    [Col1] ASC,
    [Col2] ASC,
    [Col3] ASC,
    [Col4] ASC,
    [Modified] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ThirteenMonthPartScheme (Modified)
GO

ย้ายรหัส

USE Audit_New
GO
DBCC TRACEON(610);

INSERT INTO AuditTable
SELECT * FROM Audit.dbo.AuditTable
WHERE Modified >= '6/1/2015'
ORDER BY Modified

RE "ย้ายข้อมูล": เพื่อลดการใช้บันทึกคุณสามารถย้ายข้อมูลใน batches เช่น "approch 2" ในdba.stackexchange.com/a/139009/94130 ในเรื่องของการแบ่งพาร์ติชั่นคุณถือว่ามุมมองที่ถูกแบ่ง
อเล็กซ์

@ Alex ใช่ฉันได้พิจารณาทั้งสองอย่างแล้ว แผนสำรองของฉันคือการย้ายข้อมูลเป็นชุดโดยใช้ SSIS และสำหรับกรณีนี้ปัญหาของฉันคือการแบ่งพาร์ติชันที่สร้างขึ้น (การโหลด / ยกเลิกการโหลดข้อมูลอย่างรวดเร็วโดยใช้การสลับ)
Kenneth Fisher

คำตอบ:


10

ทำไมคุณไม่ได้รับการบันทึกขั้นต่ำ

ฉันพบคู่มือการโหลดข้อมูลที่คุณอ้างอิงว่าเป็นทรัพยากรที่มีค่าอย่างยิ่ง อย่างไรก็ตามมันยังไม่ครอบคลุม 100% และฉันสงสัยว่ากริดนั้นซับซ้อนพออยู่แล้วที่ผู้เขียนไม่ได้เพิ่มคอลัมน์Table Partitioningเพื่อแยกความแตกต่างในพฤติกรรมขึ้นอยู่กับว่าตารางที่ได้รับการแทรกถูกแบ่งพาร์ติชันหรือไม่ ดังที่เราจะเห็นในภายหลังข้อเท็จจริงที่ว่าตารางถูกแบ่งพาร์ติชันแล้วปรากฏขึ้นเพื่อยับยั้งการบันทึกขั้นต่ำ

ป้อนคำอธิบายรูปภาพที่นี่

วิธีการที่แนะนำ

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

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

ความแตกต่างเมื่อเปรียบเทียบกับวิธีการเดิมของคุณ:

  • วิธีการเคลื่อนย้ายข้อมูล 12-13 เดือนล่าสุดจะมีประสิทธิภาพมากขึ้นหากคุณโหลดลงในกองTABLOCKหนึ่งครั้งต่อเดือนโดยใช้การสลับพาร์ติชันเพื่อวางข้อมูลลงในตารางที่แบ่งพาร์ติชัน
  • DELETEเพื่อล้างตารางเก่าจะถูกบันทึกไว้อย่างเต็มที่ บางทีคุณอาจจะสามารถTRUNCATEหรือวางตารางและสร้างตารางเก็บถาวรใหม่

การเปรียบเทียบวิธีการย้ายข้อมูลปีที่ผ่านมา

เพื่อเปรียบเทียบวิธีการในระยะเวลาที่เหมาะสมในเครื่องของฉันฉันใช้100MM rowชุดข้อมูลทดสอบที่ฉันสร้างขึ้นและตามสกีมาของคุณ

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

ป้อนคำอธิบายรูปภาพที่นี่

นี่คือสคริปต์ทดสอบเต็มรูปแบบ

บันทึกสุดท้าย

ผลลัพธ์ทั้งหมดนี้ขึ้นอยู่กับฮาร์ดแวร์ของคุณในระดับหนึ่ง อย่างไรก็ตามการทดสอบของฉันดำเนินการในแล็ปท็อปแบบ quad-core มาตรฐานที่มีดิสก์ไดรฟ์หมุน อาจเป็นไปได้ว่าการโหลดข้อมูลควรเร็วขึ้นมากหากคุณใช้เซิร์ฟเวอร์ที่เหมาะสมซึ่งไม่มีโหลดอื่น ๆ จำนวนมากในขณะที่คุณดำเนินการตามกระบวนการนี้

ตัวอย่างเช่นฉันใช้วิธีที่แนะนำบนเซิร์ฟเวอร์ dev จริง (Dell R720) และเห็นการลดลง76 seconds(จาก156 secondsบนแล็ปท็อปของฉัน) ที่น่าสนใจวิธีการเดิมของใส่ลงในตารางแบ่งพาร์ติชันไม่ได้พบการปรับปรุงเดียวกันและยังคงใช้เวลาเพียงกว่า12 minutesบนเซิร์ฟเวอร์นักพัฒนาซอฟต์แวร์ สันนิษฐานว่าเป็นเพราะรูปแบบนี้ให้แผนการดำเนินการแบบอนุกรมและตัวประมวลผลเดียวบนแล็ปท็อปของฉันสามารถจับคู่ตัวประมวลผลเดียวบนเซิร์ฟเวอร์ dev


ขอบคุณอีกครั้งเจฟฟ์ ฉันใช้วิธีสวิทช์ โดยเฉพาะฉันใช้ SSIS และ SQL แบบไดนามิกเพื่อให้ทำงานได้ 13 เดือนในแบบคู่ขนาน
Kenneth Fisher

1

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


0

บางทีแทนที่จะสร้างฐานข้อมูลใหม่ให้กู้คืนฐานข้อมูลจริงไปยังฐานข้อมูลใหม่และลบข้อมูลล่าสุด 12-13 เดือน จากนั้นในฐานข้อมูลจริงของคุณลบข้อมูลที่ไม่ได้อยู่ในพื้นที่เก็บถาวรที่คุณเพิ่งสร้างขึ้น หากการลบขนาดใหญ่เป็นปัญหาคุณอาจเพียงแค่ลบชุด 10K หรือใหญ่กว่าโดยใช้สคริปต์เพื่อทำมัน

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


ฉันเคยทำมาแล้วกับฐานข้อมูลขนาดเล็กมาก่อน ด้วยขนาดปัจจุบันและความจริงที่ว่าฉันต้องการที่จะจบลงด้วยตารางที่แบ่งพาร์ติชันทั้งสองด้านฉันคิดว่าวิธีนี้จะใช้เวลานานกว่า & พื้นที่เพิ่มขึ้นเล็กน้อย (เพิ่มขนาดฐานข้อมูลปัจจุบันเป็นสองเท่า)
Kenneth Fisher
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.