เพิ่มประสิทธิภาพการแทรกภายใต้ภาระ: ทำไม?


19

ฉันมีโค้ดที่ทำหน้าที่แทรกลงในตารางที่มีความผิดปกติอย่างมาก ตารางมีจำนวนคอลัมน์ตั้งแต่ ~ 100 ถึง 300+ นี่คือ SQL Server 2008 R2 ทำงานบน Windows Server 2008

แต่ละแทรกประกอบด้วยการแทรกจำนวนตารางภายใต้การทำธุรกรรมเดียวกัน เม็ดมีดบางรุ่นจะถูกแบตช์โดย NHibernate แต่บางอันไม่สามารถทำได้ แต่ทั้งหมดนั้นอยู่ภายใต้ธุรกรรมเดียวกันอย่างไรก็ตาม

เมื่อฉันทำการแทรกประมาณ 500 ครั้งโดยการเรียกรหัสที่มีการแทรกซ้ำหลายครั้งฉันจะได้รับค่าเฉลี่ย ~ 360 ms

บิตแปลกคือเมื่อฉันเรียกใช้รหัสทดสอบพร้อมกันโดยใช้ 4 กระบวนการ (exe เดียวกันทำงานจาก 4 พร้อมรับคำสั่งที่แตกต่างกันภายใต้ windows server 2008) ประสิทธิภาพการแทรกต่อการโทรดีขึ้นมาก ฉันเห็นการระเบิดที่ความเร็ว 90 มิลลิวินาที (เกือบ X4 เร็วขึ้น) ฉันวัดเวลาการแทรกจากโค้ด

เนื่องจากกระบวนการทั้งสี่ไม่รู้อะไรเกี่ยวกับกันและกันฉันจึงสมมติว่ามันมีบางอย่างที่เกี่ยวข้องกับ SQL Server แต่ฉันไม่รู้ว่าทำไม ฉันต้องการทราบว่าทำไมสิ่งนี้ถึงเกิดขึ้นและหากมีการกำหนดค่าใด ๆ ที่จะทำให้ฉันได้รับประสิทธิภาพเดียวกันเมื่อส่วนแทรกไม่บ่อย

คำแนะนำเกี่ยวกับวิธีการตรวจสอบ SQL Server เพื่อทำความเข้าใจว่าเกิดอะไรขึ้นที่ระดับ db ยินดีอย่างเท่าเทียมกัน

คำตอบ:


15

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

เมื่อต้องการตรวจสอบว่าทรานแซคชันทรานแซคชันปริมาณ / ล้างขนาดเป็นปัจจัยจอภาพ:

  • Sys.dm_os_wait_stats มุมสำหรับWRITELOGและLOGBUFFERรอ
  • sys.dm_io_pending_io_requestsสำหรับประสิทธิภาพ IO
  • ตัวนับการตรวจสอบประสิทธิภาพ (หรือsys.dm_os_performance_counters ) สำหรับ:
    • Log Bytes Flushed / วินาที
    • ล็อกฟลัช / วินาที
    • บันทึกเวลารอล้าง

มองหาขีด จำกัด ภายในที่ถึง ใน SQL Server 2008 R2 สามารถมีได้สูงสุด 32 ล้าง (แบบอะซิงโครนัส) ล็อก I / O ต่อฐานข้อมูลในรุ่น 64 บิต (8 เท่านั้นใน 32 บิต) นอกจากนี้ยังมีการ จำกัด ขนาดโดยรวมใน IOs ที่โดดเด่นที่ 3840KB

ข้อมูลเพิ่มเติมและอ่านเพิ่มเติม:


12

ทุกอย่างที่ @ PaulWhite พูดพร้อม ...

หากคุณมีกุญแจต่างประเทศอยู่ในตัวการใส่ทุกครั้งจะต้องมีการตรวจสอบที่จะทำในแต่ละตารางที่อ้างอิง ฟังดูแล้วเหมือนกับว่าคุณเป็นเพราะคุณเพิ่งได้รับ 360ms ซึ่งทำให้ฉันรู้สึกช้า

อย่างไรก็ตามการตรวจสอบตารางเหล่านั้นได้รับการช่วยเหลืออย่างมากโดยมีข้อมูลนั้นอยู่ใน RAM แล้วแทนที่จะต้องโหลดลงในดิสก์

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

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


ขอบคุณ Rob ปัญหาประสิทธิภาพการทำงานของฉันเชื่อมโยงกับตารางจำนวนสูงที่ใช้ระหว่างการแทรก ไม่มีคีย์ต่างประเทศฉันลบออกด้วยเหตุผลด้านประสิทธิภาพและความต้องการรุ่นและโดเมนของฉันอนุญาตให้ทำเช่นนั้นได้ ฉันไม่ได้โหลดข้อมูลไปที่ RAM และส่วนแทรกของฉันมีรูปร่างแบบไดนามิกโดยคำขอเข้ามาซึ่งกำลังเปลี่ยนแปลงอยู่ตลอดเวลา ฉันกำลังใช้สคีมาดาว / เกล็ดหิมะ (ish) ในทางที่ผิดสำหรับ OLTP และพยายามหลีกเลี่ยงประสิทธิภาพที่ดีที่สุดที่ฉันสามารถทำได้
mahonya

2
@mahonya แม้ว่าคุณจะไม่ได้โหลดข้อมูลลงใน RAM อย่างชัดเจน แต่ SQL Server จะต้องอ่านดัชนีและหน้าข้อมูลที่ต้องการลงในแคชแคชก่อนดำเนินการแทรก เธรดที่แทรกพร้อมกันอาจมีผลของการทำให้แคชอุ่นขึ้นซึ่งเธรดหนึ่งจะเกิดโอเวอร์เฮดสำหรับการอ่านและอีกอันจะเข้าถึงข้อมูลในแคช
Dan Guzman

ขอบคุณ @DanGuzman - และใช่ mahonya มีโอกาสสูงที่แคชของคุณจะได้รับความอบอุ่น ฉันจะตรวจสอบการรอของคุณเพื่อดูว่า I / O ทางกายภาพทำให้เกิดคอขวดของคุณ
Rob Farley

ขอบคุณ @DanGuzman เห็นด้วยความเร็วของแคชดัชนี db เป็นสิ่งที่ฉันเคยเห็นใน postgres ฉันอาจเข้าใจผิดอินพุตของ Rob
mahonya

-3

เซิร์ฟเวอร์ / cpus / os บางตัวจำรูปแบบได้ เช่นแคช

เมื่อคุณทำสิ่งเดียวกัน 4 ครั้งฉันแน่ใจว่ามีวิธีที่สามารถตัดมุมสิ่งที่ฉันเดาก็คือวิธีแรกที่คุณทำมันคิดว่ามันเป็นกระบวนการที่ยาวนาน (ตัวอย่างที่ 1) แต่ในวิธีที่สอง เห็นรหัสที่นำกลับมาใช้ใหม่และรันเหมือนแคช (ตัวอย่างที่ 2) หรืออาจเป็นกระบวนการแรกคือการใหญ่เพื่อให้พอดีกับทุกอย่างใน (ram ตัวอย่างที่ 3)

ตัวอย่างที่ 1: 0111110000110111110000111011111000011110111110000

ตัวอย่าง 2: 0111110000 | 11 | 0111110000 | 111 | 0111110000 | 1111 | 0111110000

example3: 0111110000011111000001111100000111110000 example3: loop: 0111110000

ฉันรู้ว่าเซิร์ฟเวอร์ ubuntu ทำสิ่งนี้ด้วยการสืบค้น mysql ซ้ำ ๆ ฉันสามารถบันทึกไว้ในแคชแม้ว่าจริงๆแล้วความแตกต่างในเวลาเดียวคือ 10-40 มม. แต่มันเพิ่มขึ้น เมื่อฉันอยู่ในโรงเรียนมีคลาสที่แสดงว่าคุณต้องสร้างโปรแกรม (perl / php) ใช้แคชนั้นเพื่อให้เร็วขึ้น

แต่มันอาจขึ้นอยู่กับโปรแกรมภาษาอะไรมันคืออะไรคอมไพล์มันหรือมันถูกตั้งโปรแกรม

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