การอัปเดตตารางที่มีการบันทึกนับล้านรายการมันใช้เวลา 4 วัน


12

ขณะนี้ฉันกำลังอัปเดตตารางที่มีเรคคอร์ดนับล้านระเบียนอยู่ในช่วง 4 วันและคิวรียังดำเนินการอยู่

ฉันตรวจสอบกิจกรรมการตรวจสอบแสดงว่าแบบสอบถามกำลังทำงานอยู่

ในบันทึกเหตุการณ์ไม่มีข้อผิดพลาดเลย

ประสิทธิภาพที่ชาญฉลาด:

  • Tempdb ในดิสก์ A (พื้นที่ว่าง 850 gb)
  • ไฟล์ฐานข้อมูลในดิสก์ B (พื้นที่ว่าง 750 gb)
  • RAM 16 GB

กรุณาแนะนำฉันฉันควรทำอย่างไร?

แบบสอบถาม

UPDATE
    dbo.table1
SET 
    costPercentage = ISNULL(t2.PaymentIndex, 1.0),
    t2.TopUp_Amt = (ISNULL(t2.PaymentIndex, 1.0) - 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00),
    Total_Tariff_Inc_t2 = ISNULL(t2.PaymentIndex, 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00)
FROM
    dbo.table2 t2
WHERE
    LEFT(dbo.test1.procodet, 3) = LEFT(t2.ProviderCode, 3) COLLATE database_default 

คำตอบ:


3

มีรายละเอียดที่น่าสนใจสำหรับข้อความค้นหานี้ที่ฉันไม่ได้พบเห็นในตอนแรก ขอบคุณคำตอบของ Fabricio Araujo ตอนนี้ฉันเห็นแล้ว: คุณกำลังเข้าถึงสองตาราง ฉันไม่เคยเห็นการใช้คำสั่ง update ประเภทนี้มาก่อนและฉันไม่แนะนำให้ใช้ ฉันขอแนะนำให้คุณใช้ไวยากรณ์การเข้าร่วมที่ใช้งานง่ายขึ้นตามคำตอบของ Fabricio

สาเหตุที่เป็นไปได้คือการเข้าร่วมระหว่างสองตารางจะทำให้เกิดจำนวนแถวมาก สิ่งนี้อาจเกิดขึ้นหากLEFT(col, 3)นิพจน์สร้างค่าซ้ำกัน หากผลิตซ้ำกัน 10 รายการจะส่งผลให้ 100000x100000 = 10000000000 แถวในผลการเข้าร่วม

ฉันไม่คิดว่าการจัดทำดัชนีมีบทบาทที่นี่ SQL Server สามารถแก้ไขการรวม unindexed นี้ได้ดีกับแฮชหรือการรวมการผสาน ไม่ใช้เวลา 4 วัน

สาเหตุอีกประการหนึ่งอาจเป็นเพราะการประเมินอินพุตหรือเอาต์พุตของการมีส่วนร่วมต่ำเกินไป SQL Server อาจเลือกการเข้าร่วมแบบวนซ้ำ

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


8

แบบสอบถามนี้ต้องการให้คุณสแกนทุกแถวในตารางเพราะ

  • ฉันเดา procodet หรือ ProviderCode ไม่ได้จัดทำดัชนี
  • แม้ว่าพวกเขาจะได้รับการจัดทำดัชนีคุณจะมี LEFT ซึ่งเป็นฟังก์ชั่นของคำสั่ง WHERE
  • และคุณก็มี COLLATE ด้วยเช่นกันซึ่งเป็นฟังก์ชั่นที่มีประสิทธิภาพในส่วนคำสั่ง WHERE

"ฟังก์ชั่นในเพรดิเคต WHERE" หมายถึงดัชนีจะไม่ถูกใช้

หากคุณแบทช์ (พูดกับ UPDATE TOP (10,000) ... และ costPercentage ว่างเปล่า) ดังนั้นคุณจำเป็นต้องมีดัชนีใน costPercentage และสิ่งนี้ถือว่าคุณกำลังตั้งค่ามัน

ทางออกเดียวที่ฉันเห็นคือ

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

@ gbn .. ขอบคุณที่เป็นความคิดที่ดี .. แต่เนื่องจากข้อมูลเป็นล้านกระบวนการนี้จะใช้เวลา .... ฉันคิดว่าอาจจะมีวิธีการค้นหาความคืบหน้าของการค้นหาหรือไม่
โชคดี

1
เหตุใดจึงต้องใช้เวลา 4 วันในการสแกนแถว "ล้าน"? ไม่ว่าแถวใหญ่และจัดทำดัชนีจะหนักขนาดไหนไม่ควรใช้เวลา 4 วัน รากของปัญหายังไม่ทราบ
usr

1
หากคุณจัดการกับข้อมูลขนาดใหญ่อย่างสม่ำเสมอสิ่งที่เกี่ยวกับคุณจะได้รับเซิร์ฟเวอร์ที่เหมาะสมสำหรับสิ่งนั้น ใส่ข้อมูลใน SSD ฯลฯ ..
TomTom

1
@ โชคดีแน่นอน ฉันกำลังตอบคำถาม มีบางอย่างผิดปกติที่เรายังไม่พบ ไม่ใช่แบบสอบถามด้วยตัวเองหรือฮาร์ดแวร์ นั่นจะไม่มีระยะเวลา 4 วัน
usr

3
ระบุว่าแบบสอบถามกำลังเข้าร่วมส่วนอักขระ 3 ตัวของคอลัมน์กับส่วนอักขระ 3 ตัวของคอลัมน์อื่นผลลัพธ์จะมีซ้ำกันมากกว่า สิ่งนี้แย่กว่าการอัปเดตหลายล้านแถว ฉันพนันว่ามันกำลังสแกนตารางงานในพันล้าน
datagod

4

ก่อนอื่นเปลี่ยนคิวรีเป็น:

UPDATE t1
SET 
    costPercentage = ISNULL(t2.PaymentIndex, 1.0),
    t2.TopUp_Amt = (ISNULL(t2.PaymentIndex, 1.0) - 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00),
    Total_Tariff_Inc_t2 = ISNULL(t2.PaymentIndex, 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00)
FROM
  dbo.table1 t1
  inner join dbo.table2 t2
    on LEFT(t1.procodet, 3) = LEFT(t2.ProviderCode, 3) COLLATE database_default 

ตามที่ระบุโดยโพสต์แรกของ Jeff Moden ในการสนทนานั้นข้อความค้นหาของคุณคล้ายกับข้อความที่เขาเตือนเกี่ยวกับ "เอฟเฟ็กต์ฮาโลวีน"

หลังจากนั้นนิพจน์ LEFT เหล่านั้นจะต้องถูกทำดัชนี คำตอบของ gbn ให้คำแนะนำแก่คุณในการทำเช่นนั้น

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