ถ่ายโอนข้อมูลจำนวนมาก (84 ล้านแถว) ของข้อมูลอย่างมีประสิทธิภาพ


11

ฉันมีแถวประมาณ 84 ล้านแถว พวกเขาทั้งหมดจะต้องถูกถ่ายโอนไปยังฐานข้อมูลแยกต่างหากบนเซิร์ฟเวอร์เดียวกันจากนั้นฉันลบเพื่อลบประมาณ 60 ล้านแถวจากฐานข้อมูลต้นทาง

84 ล้านแถวทั้งหมดอยู่ในตารางเดียวกัน ตารางนั้นคิดเป็น 90% ของฐานข้อมูลทั้งหมด

ดังนั้น ... ที่มา: 84 ล้านแถว -> 24 ล้านแถวปลายทาง: 0 แถว -> 84 ล้านแถว

แหล่งที่มาใช้โหมดการกู้คืนแบบเต็มปลายทางจะใช้งานง่าย

ฉันสงสัยว่าอะไรจะเป็นวิธีที่มีประสิทธิภาพที่สุดในการทำสิ่งนี้?

แผนก:

1) INSERT INTO destination SELECT * จากแหล่งที่มา

2) แหล่งที่มาตัด

3) INSERT INTO SELECT เลือก * จากปลายทาง WHERE keep_condition = 1

แผนข:

1) คืนค่าสำเนาสำรองของฐานข้อมูลต้นทางเป็นฐานข้อมูลปลายทาง

2) วางทุกตารางยกเว้นตารางที่จำเป็นบนฐานข้อมูลปลายทาง

3) แหล่งที่มาตัด

4) INSERT INTO SELECT เลือก * จากปลายทาง WHERE keep_condition = 1

แผน C:

1) INSERT INTO destination SELECT * จากแหล่งที่มา

2) ลบแหล่ง WHERE keep_condition = 0

หรืออย่างอื่น?

ขอบคุณ


ทำไมคุณไม่ใช้ตัวช่วยสร้างการนำเข้าและส่งออกข้อมูล มันเป็นเครื่องมือที่ให้มาพร้อมกับการติดตั้ง SQL Server
Hani El Mouallem

เป็นไปได้หรือไม่ที่จะคัดลอก 24 ล้านแถวไปยังตารางใหม่จากนั้นเปลี่ยนชื่อทั้งสองตามต้องการเพื่อที่คุณจะไม่ย้าย 84 ล้านแถวโดยไม่จำเป็น?
LowlyDBA

นี่เป็นกระบวนการแบบครั้งเดียวหรือต่อเนื่องหรือไม่ ฉันถามเพราะให้เวลาในการประมวลผลแถว 80M มีโอกาสที่จะมีการเปลี่ยนแปลงข้อมูลในแหล่งผลิตแถวซึ่งตอนนี้ควรจะอยู่ใน DESTINATION
Michael Green

นี่ดูเหมือนปัญหา XY: คุณต้องจบด้วยแถว 84MM ทั้งหมดในหนึ่งฐานข้อมูลและ 24 มิลลิเมตรในแถวที่สอง ข้อกำหนดทางธุรกิจอะไรที่ต้องมีการย้าย 84 มม. และลบ 60M แทนที่จะเป็น 24 มม. แบบเคลื่อนที่ ลิงค์: meta.stackexchange.com/questions/66377/what-is-the-xy-problem )
Pieter Geerkens

ฉันมีปัญหาที่คล้ายกันมากและเห็นได้ชัดว่าไม่ใช่ XY ก่อนที่จะมีการเผยแพร่กฎหมายที่เกี่ยวข้องกับการเก็บบันทึกเราได้เก็บข้อมูลทั้งหมดไว้ ตอนนี้เราต้องลบแถวที่เก่ากว่าวันที่เราจำเป็นต้องใช้ตามกฎหมายเพื่อให้พวกเขา ซึ่งหมายถึงการเก็บถาวรและการลบข้อมูลมากกว่า 20 ปีเพราะการเก็บรักษาตามกฎหมายในกรณีส่วนใหญ่คือ 7 ปี ฉันไม่คิดว่าฉันคนเดียวที่เชื่อว่าไมโครซอฟท์มีความสะเพร่าในการไม่ให้ฟังก์ชั่น แอปไม่ควรเร็วกว่าในการเคลื่อนย้ายข้อมูล 'ภายใน' a ฐานข้อมูลกว่าฐานข้อมูลตัวเอง ปีหน้าอีกปีหนึ่งจะต้องถูกเก็บถาวร
bielawski

คำตอบ:


11

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

แม้แต่การบันทึกเพียงเล็กน้อยก็เป็นธุรกรรมขนาดใหญ่และคุณสามารถใช้เวลามากมายในการจัดการกับการเติบโตของบันทึกที่ผิดปกติ (VLFs, การตัดทอน, การปรับขนาดขวา ฯลฯ )

ขอบคุณ


3

"ประสิทธิภาพ" สามารถนำไปใช้กับการใช้งานไฟล์บันทึกประสิทธิภาพ I / O เวลา CPU หรือเวลาดำเนินการ

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

CREATE TABLE #temp;
ALTER source -> BULK_LOGGED recovery model

BEGIN TRANSACTION;

    INSERT INTO dest SELECT FROM source;
    INSERT INTO #temp SELECT FROM source WHERE keep_condition=1;
    TRUNCATE TABLE source;
    INSERT INTO source SELECT FROM #temp;

COMMIT TRANSACTION;

ALTER source -> FULL recovery model
DROP TABLE #temp;

เพื่อให้การดำเนินการเข้าสู่ระบบน้อยที่สุดจำนวนเงื่อนไขต้องเป็นจริงรวมถึงไม่มีการสำรองข้อมูลที่ทำงานอยู่ในปัจจุบันฐานข้อมูลที่ตั้งค่าเป็นBULK_LOGGEDโหมดการกู้คืนและขึ้นอยู่กับดัชนีของคุณตารางเป้าหมายอาจต้องว่างเปล่า พฤติกรรมบางอย่างนี้ก็เปลี่ยน (ปรับปรุง) จาก SQL Server 2005 เป็น 2008

จากนั้นอีกครั้งโดยไม่ทราบข้อมูลเฉพาะของตารางและข้อมูลของคุณตัวเลือกอื่นใดของคุณอาจทำงานได้ดีขึ้น ลองใช้ดู

SET STATISTICS IO ON;
SET STATISTICS TIME ON;

.. และดูว่าอะไรดีที่สุด

แก้ไข : เมื่อทำการดำเนินการบันทึกจำนวนมากตรวจสอบให้แน่ใจว่าคุณทำการสำรองข้อมูล (บันทึกเต็มหรือธุรกรรม) ก่อนและหลังการดำเนินการหากคุณต้องการความสามารถในการกู้คืน ณ จุดเวลาและคุณสงสัยว่ากิจกรรมอื่น ๆ อาจเกิดขึ้นในฐานข้อมูล ในเวลาเดียวกันกับที่งาน ETL ของคุณกำลังทำงานอยู่

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


+1 สำหรับการให้คำแนะนำ OP เพื่อทดสอบเพื่อดูว่าแบบไหนดีกว่ากัน แน่นอนว่าอาจเป็นเรื่องยากที่จะได้รับจำนวนจริงนอกเสียจากว่าเขามีระบบซ้ำซ้อนใน dev และอื่น ๆ
Max Vernon

แค่คำถามจะเกิดอะไรขึ้นถ้าคุณพยายามกู้คืนจุดเมื่อฐานข้อมูลอยู่ในโหมดบันทึกจำนวนมาก? ฉันคิดว่าการทำธุรกรรมใด ๆ ที่ไม่ผ่านการรับรองว่า "เป็นกลุ่ม" จะสามารถกู้คืนได้
elty123

1
@ elty123 ในการกู้คืนที่บันทึกจำนวนมากคุณสามารถกู้คืนได้แล้วจึงสิ้นสุดการสำรองข้อมูลบันทึกล่าสุดของคุณ ไม่มีเวลาในการกู้คืนเหมือนจะมีการกู้คืนเต็ม โดยปกติแล้วคุณจะเปลี่ยนไปใช้การกู้คืนข้อมูลที่บันทึกจำนวนมากเรียกใช้กระบวนการ ETL บางส่วนเปลี่ยนกลับเป็นเต็มและทำการสำรองข้อมูลบันทึก
RubberChickenLeader

@WindRaven ไม่ถูกต้อง - ดูคำตอบของฉันด้านล่าง
wBob

1
@wBob และ @WindRaven ฉันได้อัปเดตคำตอบของฉันเพื่อสะท้อนถึงความจำเป็นในการสำรองข้อมูลก่อนและหลังการใช้BULK_LOGGEDโหมด ขอบคุณ!
Daniel Hutmacher

1

ทำไมไม่ BCP

  1. สำรองแหล่งที่มา
  2. เปลี่ยน sourcedb เป็นบันทึกจำนวนมาก
  3. พร้อมรับคำสั่งเปิด

  4. bcp server.sourcedb.table out Filename.flt -T -c

  5. bcp "SELECT * FROM sourcedb.table WHERE keep_condition = 1" queryout Filename2.flt -T -c

  6. bcp Server.destinationdb.table in Filename.flt -T -c -b1000

  7. ตรวจสอบข้อมูล

  8. จาก SSMS ตัดทอนตาราง sourcedb
  9. bcp server.sourcedb.table in Filename2.flt -T -c -b1000
  10. เปลี่ยน sourcedb กลับเป็นเต็ม

2
เพราะพวกเขาอยู่บนเซิร์ฟเวอร์เดียวกัน การเขียนระบบไฟล์อาจมีราคาแพง ดีกว่าในการสร้างฐานข้อมูลและตั้งค่าหวังว่าจะได้ประโยชน์จากการเริ่มต้นไฟล์ทันที นี่จะเป็นตัวเลือกที่สมเหตุสมผลสำหรับ dbs บนเซิร์ฟเวอร์ต่าง ๆ แม้ว่า SSIS จะเป็นตัวเลือกแรกของฉันหากมี หมายเหตุ: ตัวเลือก - n (ดั้งเดิม) มีขนาดกะทัดรัดและปลอดภัยยิ่งขึ้นสำหรับการย้ายข้อมูลจาก SQL Server ไปยัง SQL Server ตัวเลือก -b ไม่มีผลกระทบสำหรับ bcp out
wBob

0

อย่าคิดว่าคุณควรจะได้รับการแนะนำให้เปลี่ยนรูปแบบการกู้คืนโดยไม่ต้องทั้งการสำรองฐานข้อมูลหรือเสื้อเข้าสู่ระบบสำรองข้อมูลทั้งหมดก่อนและหลัง หนึ่งในคุณสมบัติของแบบจำลองการกู้คืน BULK_LOGGED คือคุณจะสูญเสียความสามารถในการกู้คืนข้อมูล ณ จุดเวลาสำหรับบันทึก t ที่มีการดำเนินการบันทึกจำนวนมาก สถานการณ์แบบคลาสสิก: การสำรองข้อมูลเต็มรูปแบบทุกคืน, การสำรองข้อมูล t-log ทุกชั่วโมง คุณเปลี่ยนรูปแบบการกู้คืนเป็นบันทึกจำนวนมากและเริ่มการทำงานของคุณ เกิดข้อผิดพลาดบางอย่างและการทำธุรกรรมย้อนกลับ (หรือคุณไม่ได้ใช้) อย่างไรก็ตามคุณไม่แน่ใจว่ามีอะไรเกิดขึ้นในฐานข้อมูลอีกดังนั้นคุณต้องการคืนค่าไปยังจุดที่ทราบดี

คุณสามารถคืนค่ากลับเป็นเมื่อใด ล่าสุดสำรองเสื้อบันทึกรายชั่วโมงที่ไม่ได้มีการดำเนินงานจำนวนมากเข้าสู่ระบบอาจสูญเสียนาที n ของการทำธุรกรรม การสำรองข้อมูลเต็มรูปแบบหรือการสำรองข้อมูล t-log ก่อนที่จะเปลี่ยนรูปแบบการกู้คืนจะสร้างจุดทางเลือก สิ่งที่คุณเลือกขึ้นอยู่กับ RTO ของคุณ


0

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

ต้นทุนของการเปิดใช้งานการแบ่งพาร์ติชันอาจทำให้การดำเนินการโดยรวมมีราคาแพงกว่า

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