SQL Server - ส่งออกตารางขนาดใหญ่โดยไม่มีคีย์หลัก


9

ฉันต้องการซิงค์ตารางขนาดใหญ่ ~ 500 ล้านแถวโดยไม่มีคีย์หลักระหว่าง SQL Server และ MySQL ตารางมีดัชนีที่ไม่ซ้ำแบบรวมที่ไม่ซ้ำกันเท่านั้น

ฉันมีการเชื่อมต่อ ODBC ระหว่างเซิร์ฟเวอร์ แต่การนำเข้าประมาณ 8 ล้านแถวใช้เวลาประมาณ 45 นาทีดังนั้นฉันเชื่อว่าการนำเข้าที่ใหญ่กว่านั้นจะไม่มีเหตุผลเนื่องจากการหยุดชะงักอาจเกิดขึ้นได้ทุกเมื่อ ฉันไม่สามารถเปลี่ยนโครงสร้างตารางที่มีอยู่ฉันสามารถเพิ่มตารางอื่น ๆ ได้ หลังจากอ่านเพิ่มเติม offset / fetch ไม่ใช่ตัวเลือกสำหรับตารางขนาดใหญ่ "เลือก ... โดยที่ x ระหว่าง ... และ ... " ไม่ใช่ตัวเลือกเนื่องจากฉันไม่มีคีย์ที่ไม่ซ้ำ

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


สิ่งนี้จะเกิดขึ้นซ้ำ (การดำเนินการโดยไม่ได้ตั้งใจ) หรือการดำเนินการครั้งเดียว
Bogdan Bogdanov

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

ฉันคิดว่าจะได้รับความช่วยเหลือในเรื่องนี้คุณต้องอธิบายรายละเอียดเพิ่มเติมเกี่ยวกับกระบวนการทั้งหมด (ดูว่าคุณมีปัญหาซับซ้อนมาก)
Bogdan Bogdanov

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

ใช่ RLF ฉันเห็นด้วย คอลัมน์เป็น ints ทั้งหมด A, B, C, D, E. คีย์คลัสเตอร์อยู่ใน ABC ABC รวมกันไม่ซ้ำกันไม่มี ABCD รวมกัน คอลัมน์ "ที่ไม่ซ้ำกัน" จะทำให้ฉันสามารถส่งออกตารางทั้งหมดเป็นชุดได้หรือไม่ และบ็อกแดนโบดานอฟแพลตฟอร์มสแต็คช่วยลดปัญหาที่ซับซ้อนได้ดีกว่าที่จะตอบคำถาม วิธีการส่งออกตารางขนาดใหญ่สมบูรณ์เร็วที่สุดเท่าที่จะทำได้โดยไม่สูญเสียแถว?
ไม่มีใคร

คำตอบ:


0

สมมติว่าคุณไม่มีการปรับปรุงหรือลบกับตารางต้นฉบับคุณสามารถลองทำสิ่งต่อไปนี้:
1. สร้างสำเนาของตารางที่มีอยู่โดยใช้ไวยากรณ์ CTAS (สำหรับ SQLServer SELECT * into source_table_copy FROM source_table) การดำเนินการดังกล่าวเป็นไปอย่างรวดเร็วแม้สำหรับโต๊ะขนาดใหญ่
2. เพิ่มafter insertทริกเกอร์บนsource_tableสำเนาบันทึกใหม่ [s] source_table_copyเพื่อ
3. ตอนนี้เมื่อระเบียนใหม่ทั้งหมดsource_tableไปsource_table_copyด้วยเช่นกันและคุณสามารถย้ายข้อมูลจากตารางที่คัดลอกไปยัง Mysql ในแบตช์ ตัวอย่างเช่นหากคุณมีลิงก์ระหว่าง 2 เซิร์ฟเวอร์ทุกสิ่งสามารถทำได้ภายในเนื้อความของ TSQL ที่เก็บไว้ในกระบวนงาน
เช่นโค้ดบางส่วนที่เลื่อนไปถึง 20 รายการไปยังเซิร์ฟเวอร์ใหม่อาจมีลักษณะเช่นนี้

 --declare table variable to keep deleted records until they delivered to target host 
  BEGIN TRANSACTION;
  DELETE TOP (20) FROM source_table_copy OUTPUT DELETED.* INTO @Table_Var;

  --insert data into linked server , or to csv file
  COMMIT; 

นอกจากนี้ยังเป็นไปได้ที่จะใช้ CURSOR เพื่ออ่านข้อมูลแล้วลบด้วยwhere current ofส่วนคำสั่ง

** เป็นการดีที่คุณต้องป้องกันไม่ให้แอปพลิเคชันแทรกข้อมูลลงsource_tableในระหว่างขั้นตอนที่ 1 ถ้ามันเป็นไปไม่ได้อย่างแน่นอนฉันจะไปด้วยafter insertทริกเกอร์ซึ่งจะถูกเพิ่มก่อนขั้นตอนที่ 1 และลบทันทีหลังจากที่ทำสำเนาข้อมูลไปยังตารางอื่น ๆ source_table_copyผสานในภายหลังด้วย


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

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