อัปเดตด้วย JOIN ในบันทึก 100 มม. ทำอย่างไรให้ดีขึ้น? (ใน T-SQL)


11

ฉันต้องการอัปเดต 100 ล้านเรคคอร์ดในตารางเดียวโดยมีผลทำให้มาตรฐานของตารางเป็นปกติโดยแทนที่ค่า varchar ของคอลัมน์ด้วย ID เพียงอย่างเดียว (ฉันพูดว่า "การแทนที่" แต่จริงๆแล้วฉันกำลังเขียน ID ลงในคอลัมน์อื่น)

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

UPDATE A
SET A.AutoClassID = B.AutoClassID
FROM AutoDataImportStaging.dbo.Automobile as A
JOIN AutoData.dbo.AutoClass as B on (A.AutoClassName = B.AutoClassName)

พื้นหลัง

  • ใช้ MSSQL 2008 R2 บนเซิร์ฟเวอร์ 2008 R2
  • เซิร์ฟเวอร์มี RAM 8 GB
  • เซิร์ฟเวอร์มีหนึ่ง RAID10, 7200 RPM SATA (ไม่ค่อยดีเท่าไหร่ในการผลิตนี้จะอ่านเฉพาะข้อมูลและไม่เขียนข้อมูลรวมถึงปัญหาการขาดแคลน HD ล่าสุดทำให้จำเป็นต้องเสียค่าใช้จ่าย)
  • เซิร์ฟเวอร์มี CPU Xeon แบบ Quad-Core คู่
  • เครื่องไม่ได้ทำอะไรอย่างอื่น (ในปัจจุบันอุทิศให้กับ dev เพียงกระบวนการนี้เท่านั้น)
  • เปิดใช้งานการบันทึกอย่างง่าย (? - แต่ยังเข้าสู่ระบบอยู่หรือไม่เพื่อให้สามารถย้อนกลับได้)
  • โปรดทราบว่าแบบสอบถามอ้างอิงสอง DB ที่แตกต่างกันสำหรับสิ่งที่คุ้มค่า
  • "width" ของระเบียนในตารางที่ได้รับการอัพเดตคือ 455 ไบต์

ทรัพยากรระหว่างการดำเนินการ

  • RAM ทางกายภาพสูงสุด
  • disk I / O maxed out
  • CPU แทบจะไม่ทำอะไรเลย (จุดทำให้หายใจไม่ออกเป็น I / O)
  • เวลาในการทำงาน 14 ชั่วโมงและเพิ่มขึ้นเรื่อย ๆ !

ฉันสงสัยว่าบางสิ่งเช่นฉันต้องการดัชนีในข้อมูลดิบแม้ว่าฉันจะวางคอลัมน์ (AutoClassName) หลังจากการปรับปรุงมาตรฐาน ฉันยังสงสัยว่าฉันควรวนตารางหนึ่งระเบียนทีละครั้งแทนที่จะเข้าร่วมซึ่งดูเหมือนไร้สาระในเวลาที่ฉันเริ่มต้นนี้ แต่ตอนนี้ดูเหมือนว่าจะเร็วขึ้น

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

คำตอบ:


7

คุณกำลังพยายามทำสิ่งนี้เป็นธุรกรรมเดียว (มีขนาดใหญ่มาก) ให้อัปเดตเป็นชุดเล็ก ๆ แทน

คุณจะได้รับประโยชน์จาก:

  • ดัชนีชั่วคราวบน AutoData.dbo.AutoClass.AutoClassName
  • RAM เพิ่มเติม RAM มากขึ้นมาก

1
+1 ฉันเห็นด้วยกับการอัปเดตแบทช์โดยใช้TOPข้อ นั่นเป็นแนวทางของฉัน
Thomas Stringer

ถ้าฉันทำ UPDATE TOP ฉันจะต้องใช้ WHERE clause (WHERE AutoClassID นั้นเป็นค่า NULL)? ส่วนคำสั่ง WHERE จะไม่แนะนำประสิทธิภาพการทำงานใหม่ (การสแกนตารางที่ฉันไม่ได้ทำตอนนี้) ไม่ต้องสงสัยเลยว่ามันจะลดปัญหา RAM ที่ฉันมีกับ JOIN
Chris Adragna

คำตอบของฉันเกินกำหนดเป็นเวลานาน แต่ในกรณีของฉัน SET ROWCOUNT ได้รับการพิสูจน์แล้วว่ามีประสิทธิภาพมากที่สุด
Chris Adragna

10

ฉันจะใช้วิธีการอื่น

แทนที่จะปรับปรุงตารางที่มีอยู่เพียงสร้างตารางใหม่ที่มีสิ่งที่คุณต้องการ

สิ่งนี้จะเร็วขึ้น:

SELECT DISTINCT
    AutoClassID,
    <Other fields>
INTO
    AutoDataImportStaging.dbo.Automobile
FROM
    AutoData.dbo.AutoClass

ตามที่เขียนไว้ในปัจจุบันมีการดำเนินการทางตรรกะเกิดขึ้นมากมาย:

  • อ่านค่าทั้งหมดของ A.AutoClassName
  • อ่านค่าทั้งหมดของ B.AutoClassName
  • เปรียบเทียบค่า A และ B
  • ของชุดการจับคู่อ่านค่าทั้งหมดของ B.AutoClassID
  • อัพเดตค่าที่มีอยู่ของ A.AutoClassId ให้เป็นค่า B.AutoClassId ผ่านดัชนีใด ๆ ก็ตามที่มีอยู่

ดูเหมือนว่าวิธีการที่ดีและเรียบง่ายโดยเฉพาะอย่างยิ่งเมื่อเกิดปัญหา I / O ของดิสก์ที่ฉันมี ขอบคุณสำหรับการตอบอย่างรวดเร็ว
Chris Adragna

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

5

การวนลูบโต๊ะในแต่ละครั้งจะไม่เร็วขึ้น!

ตามที่คุณสงสัยและได้รับการยืนยันจากคุณสิ่งนี้จะถูกผูกไว้กับ i / o ซึ่งมีดิสก์หนึ่งแผ่นอ่านเขียนบันทึกธุรกรรมและพื้นที่ทำงานชั่วคราว (ใด ๆ ) ทั้งหมดจะแข่งขันกันเพื่อ i / o เดียวกัน

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

คุณได้ลองสร้างดัชนีฟิลด์ AutoClassName หรือยัง มี AutoClass ที่แตกต่างกันกี่ค่า

คุณอาจต้องแบตช์การอัปเดตตามข้อ จำกัด ของ i / o ของคุณ ดังนั้นอัปเดต 1 ล้านจุดตรวจสอบทำซ้ำ ....


มี AutoClass เพียง 15 ค่าเท่านั้น ความคิดเห็นของคุณยืนยันข้อสงสัยของฉัน (และความเจ็บปวด!) มากมาย ขอบคุณสำหรับการตอบ
Chris Adragna

3

สร้างดัชนีสำหรับฟิลด์การเข้าร่วม

คุณสามารถวางดัชนีได้ตลอดเวลาเมื่อดำเนินการเสร็จ

ฉันจะแปลกใจมากถ้าดัชนีไม่ได้ปรับปรุงประสิทธิภาพการอัพเดตอย่างมีนัยสำคัญ


ฉันแน่ใจว่าดัชนีจะดีขึ้น ฉันคิดว่าคำถามคือพวกเขาปรับปรุงมากกว่าเวลาที่ใช้ในการสร้างดัชนี (สำหรับการใช้งานเพียงครั้งเดียวเท่านั้น) อาจจะใช่. :)
Chris Adragna

3

ส่งออกในแบบที่คุณต้องการสร้างตารางใหม่และนำเข้ากลับมา ในฐานะโบนัสคุณจะต้องมีสำเนาของข้อมูลเป็นข้อมูลสำรองหากปาฏิหาริย์เกิดขึ้น

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