เมื่อแบบสอบถาม SQL ที่เร็วกว่าเดิมเริ่มทำงานช้าฉันจะค้นหาแหล่งที่มาของปัญหาได้ที่ไหน


36

พื้นหลัง

ฉันมีแบบสอบถามที่ใช้กับ SQL Server 2008 R2 ที่รวมและ / หรือซ้ายเข้าร่วมกับ "ตาราง" ที่แตกต่างกันประมาณ 12 รายการ ฐานข้อมูลมีขนาดค่อนข้างใหญ่โดยมีตารางมากกว่า 50 ล้านแถวและประมาณ 300 ตารางที่แตกต่างกัน สำหรับ บริษัท ขนาดใหญ่ที่มีคลังสินค้า 10 แห่งทั่วประเทศ คลังสินค้าทั้งหมดอ่านและเขียนไปยังฐานข้อมูล ดังนั้นมันจึงค่อนข้างใหญ่และค่อนข้างยุ่ง

ข้อความค้นหาที่ฉันพบมีลักษณะดังนี้:

select t1.something, t2.something, etc.
from Table1 t1
    inner join Table2 t2 on t1.id = t2.t1id
    left outer join (select * from table 3) t3 on t3.t1id = t1.t1id
    [etc]...
where t1.something = 123

ขอให้สังเกตว่าหนึ่งในการรวมอยู่ในแบบสอบถามย่อยที่ไม่เกี่ยวข้อง

ปัญหาคือการเริ่มต้นเมื่อเช้านี้โดยไม่มีการเปลี่ยนแปลงใด ๆ (ที่ฉันหรือใครก็ได้ในทีมของฉันรู้) ไปยังระบบการสืบค้นซึ่งโดยปกติจะใช้เวลาประมาณ 2 นาทีในการเริ่มต้นใช้เวลาหนึ่งชั่วโมงครึ่งในการทำงาน วิ่งเลย ส่วนที่เหลือของฐานข้อมูลนั้นฮัมเพลงไปด้วยดี ฉันได้ลบแบบสอบถามนี้ออกจาก sproc ที่มันมักจะทำงานในและฉันจะเรียกใช้มันใน SSMS w / ตัวแปรพารามิเตอร์รหัสตายยากกับความช้าเหมือนกัน

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

and t.name like '%'

ฉันได้ข้อสรุป (อาจไม่ถูกต้อง) จากการทดลองเล็กน้อยเหล่านี้ว่าสาเหตุของการชะลอตัวนั้นเกิดจากการตั้งค่าแผนการดำเนินการแคชของ SQL - เมื่อแบบสอบถามแตกต่างกันเล็กน้อยก็ต้องสร้างแผนปฏิบัติการใหม่

คำถามของฉันคือ:เมื่อแบบสอบถามที่ใช้ในการเรียกใช้อย่างรวดเร็วเริ่มทำงานช้าในกลางดึกและไม่มีอะไรได้รับผลกระทบใดนอกจากแบบสอบถามนี้ฉันจะแก้ไขปัญหาได้อย่างไรและฉันจะป้องกันไม่ให้เกิดขึ้นในอนาคตได้อย่างไร ? ฉันจะรู้ได้อย่างไรว่า SQL กำลังทำอะไรภายในเพื่อทำให้มันช้ามาก (ถ้าเคียวรีไม่ดีฉันสามารถรับแผนปฏิบัติการได้ แต่จะไม่ทำงาน - บางทีแผนปฏิบัติการที่คาดหวังจะให้บางอย่างกับฉัน)? หากปัญหานี้อยู่ในแผนการดำเนินการฉันจะป้องกันไม่ให้ SQL คิดว่าแผนการดำเนินการที่เลวร้ายจริงๆเป็นความคิดที่ดีได้อย่างไร

และนี่ไม่ใช่ปัญหากับการดมพารามิเตอร์ ฉันเคยเห็นมาก่อนและนี่ไม่ใช่เพราะแม้เมื่อฉันเขียนโค้ด varaibles ใน SSMS ฉันก็ยังได้รับประสิทธิภาพที่ช้า


คุณสามารถแบ่งปันแผนแบบสอบถาม (แผนช้า) ได้ที่นี่: brentozar.com/pastetheplan
MJH

คำตอบ:


31

เมื่อแบบสอบถามที่ใช้ในการเรียกใช้อย่างรวดเร็วทันใดนั้นก็เริ่มทำงานช้าในกลางดึกและไม่มีอะไรได้รับผลกระทบใด ๆ ยกเว้นแบบสอบถามหนึ่งนี้ฉันจะแก้ไขปัญหาได้อย่างไร ... ?

คุณสามารถเริ่มต้นด้วยการตรวจสอบว่าแผนการดำเนินการยังอยู่ในแคชหรือไม่ ตรวจสอบsys.dm_exec_query_stats, และsys.dm_exec_procedure_stats sys.dm_exec_cached_plansหากแผนการดำเนินการที่ไม่ดียังคงถูกแคชคุณสามารถวิเคราะห์ได้และคุณสามารถตรวจสอบสถิติการดำเนินการได้ สถิติการดำเนินการจะมีข้อมูลเป็นการอ่านเชิงตรรกะเวลา CPU และเวลาดำเนินการ สิ่งเหล่านี้สามารถบ่งชี้อย่างชัดเจนว่าปัญหาคืออะไร (เช่นการสแกนขนาดใหญ่เทียบกับการปิดกั้น) ดูการระบุแบบสอบถามที่เป็นปัญหาสำหรับคำอธิบายวิธีตีความข้อมูล

และนี่ไม่ใช่ปัญหากับการดมพารามิเตอร์ ฉันเคยเห็นมาก่อนและนี่ไม่ใช่เพราะแม้เมื่อฉันเขียนโค้ด varaibles ใน SSMS ฉันก็ยังได้รับประสิทธิภาพที่ช้า

ฉันไม่มั่นใจ ตัวแปร Hard-coding ใน SSMS ไม่ได้พิสูจน์ว่าแผนการดำเนินการที่ไม่ถูกต้องในอดีตนั้นไม่ได้รวบรวมกับอินพุตที่เบ้ โปรดอ่านพารามิเตอร์การดม, การฝังและตัวเลือก RECOMPILEสำหรับบทความที่ดีมากในหัวข้อ ช้าในแอปพลิเคชันรวดเร็วใน SSMS หรือไม่ การทำความเข้าใจความลึกลับของผลงาน เป็นอีกหนึ่งการอ้างอิงที่ยอดเยี่ยม

ฉันได้ข้อสรุป (อาจไม่ถูกต้อง) จากการทดลองเล็กน้อยเหล่านี้ว่าสาเหตุของการชะลอตัวนั้นเกิดจากการตั้งค่าแผนการดำเนินการแคชของ SQL - เมื่อแบบสอบถามแตกต่างกันเล็กน้อยก็ต้องสร้างแผนปฏิบัติการใหม่

สามารถทดสอบได้ง่าย SET STATISTICS TIME ONจะแสดงเวลารวบรวมและเวลาดำเนินการ SQL Server:ตัวนับประสิทธิภาพของสถิติจะเปิดเผยว่าการรวบรวมเป็นปัญหาหรือไม่ (ตรงไปตรงมาฉันพบว่าไม่น่าเป็นไปได้)

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

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


7

นี่เป็นข้อ จำกัด ของการเรียกใช้แบบสอบถามที่ซับซ้อนใน SQL Server โชคดีที่มันไม่ได้เกิดขึ้นบ่อยครั้ง

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

OPTION (MERGE JOIN, HASH JOIN)

โดยทั่วไปได้แก้ไขปัญหานี้ให้ฉันในอดีต

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


1
แผนการดำเนินการใช้การเข้าร่วมลูปซ้อนกันแน่นอน อย่างไรก็ตามเมื่อฉันวางคำแนะนำตามที่คุณแนะนำฉันจะได้รับข้อผิดพลาดนี้: "ตัวประมวลผลแบบสอบถามไม่สามารถสร้างแผนแบบสอบถามได้เนื่องจากคำแนะนำที่กำหนดไว้ในแบบสอบถามนี้ส่งแบบสอบถามโดยไม่ระบุคำแนะนำใด ๆ และไม่ใช้ SET FORCEPLAN" เมื่อฉันเพิ่ม OPTION (LOOP JOIN) แน่นอนมันจะสร้างแผนการดำเนินการ แต่ฉันยังคงมีปัญหากับมันทำงานช้า คุณพบปัญหานี้หรือไม่? ดูเหมือนว่าจะต้องมีการเข้าร่วมแบบวนซ้ำ

@ เทรเวอร์ . . ไม่ฉันไม่ได้เห็นปัญหานี้จริงๆ บางทีเคียวรีของคุณกำลังทำบางอย่างที่ไม่ใช่ equijoins (ไม่ใช้เครื่องหมายเท่ากับ) และเครื่องมือเพิ่มประสิทธิภาพต้องใช้การวนซ้ำซ้อนกันที่นั่น
Gordon Linoff

3

โดยปกติแล้วจะเป็นดัชนีที่หายไปซึ่งก่อให้เกิดปัญหาประเภทนี้

สิ่งที่ฉันมักจะทำคือการเรียกใช้แบบสอบถามโดยใช้ SQL Management Studio และเปิดใช้งาน 'รวมการดำเนินการตามแผนจริง (CTRL + M)' และค้นหาว่าการเข้าร่วมใดที่มีเปอร์เซ็นต์ที่ใหญ่ที่สุด

แอปพลิเคชั่นไม่ได้มุ่งเน้นที่คอขวด แต่คุณสามารถค้นหาได้อย่างรวดเร็วเพียงแค่ดูผลลัพธ์

ตัวอย่างที่นี่: 48PercentForTop


2
แม้ว่าดัชนีจะไม่ "หายไป" โดยฉับพลันดังนั้นแม้ว่าวิธีนี้อาจปรับปรุงประสิทธิภาพ แต่ก็ไม่ได้อธิบายปัญหา
Fowl

3

ฉันเพิ่งพบปัญหาเดียวกันนี้ซึ่งนำฉันมาที่หน้านี้

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

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

ฉันหวังว่านี่จะช่วยคนอื่นได้


0

คุณต้องตรวจสอบว่ามีการสำรองข้อมูลเซิร์ฟเวอร์หรืองาน Archiving \ indexing ใด ๆ หรือไม่เมื่อคุณเห็นปัญหาประสิทธิภาพใน T-SQL \ Procedure

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