ทำไมคำถามของฉันจึงช้ากว่าเมื่อวานเมื่อวาน?


76

[Memorial ~]

(เลือกหนึ่งอัน)

[ ] Well trained professional, [ ] Casual reader, [ ] Hapless wanderer,

ฉันมี(เลือกทุกข้อที่ใช่)

[ ] query [ ] stored procedure [ ] database thing maybe  

ที่ทำงานได้ดี(ถ้ามี)

[ ] yesterday [ ] in recent memory [ ] at some point 

แต่ตอนนี้ช้าลงทันที

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

ปัญหาคือสิ่งที่ฉันควรทำอย่างไรและฉันสามารถให้ข้อมูลใดได้บ้างเพื่อรับความช่วยเหลือ

[*Insert appropriate closing remarks*]

คำตอบ:


88

เรียน [ชื่อของคุณที่นี่]!

โอ้ไม่ฉันขอโทษที่ได้ยินอย่างนั้น! เริ่มต้นด้วยพื้นฐานบางอย่างเพื่อให้คุณได้รับการแก้ไขในระยะเวลาอันสั้น

สิ่งที่คุณกำลังเรียกใช้เรียกว่าการดมกลิ่นพารามิเตอร์

มันเป็นวิธีการแก้ปัญหาที่แปลกประหลาด ชื่อม้วนออกจากลิ้น เหมือนคำภาษาเยอรมันสำหรับกระรอก

และมันมักจะเป็นเพื่อนของคุณ

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

วิธีที่ง่ายที่สุดในการถ่ายภาพสิ่งเลวร้ายนี้คือการจินตนาการถึงกระบวนงานที่เก็บไว้ซึ่งต้องนับจำนวนสิ่งของจากประชากรที่ไม่สมดุลสองกลุ่ม

ตัวอย่างเช่น:

  • ผู้คนใส่เสื้อ CrossFit ที่ไม่ได้รับบาดเจ็บ: Zero

  • ผู้คนใส่เสื้อ CrossFit ที่สะดุ้งเมื่อพวกเขาสะดุ้ง: ทั้งหมด

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

ฉันกำลังทำอะไรอยู่

นี่เป็นปัญหาที่ยากอย่างแท้จริงในการค้นหาทดสอบและแก้ไข

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

แก้ไขด่วน

บางครั้งสิ่งที่คุณต้องการคือความชัดเจนเล็กน้อย หรือค่อนข้างแคชแผนของคุณ

หากเป็นขั้นตอนการจัดเก็บ

EXEC sys.sp_recompile @objname = N'schema.procname'ลองใช้ นั่นจะทำให้ขั้นตอนการคอมไพล์แผนใหม่ในครั้งต่อไปที่มันรัน

สิ่งนี้จะไม่แก้ไข:

  • กระบวนการกำลังทำงานอยู่

สิ่งนี้ไม่รับประกัน:

  • กระบวนการถัดไปที่รันหลังจากการคอมไพล์ใหม่จะใช้พารามิเตอร์ที่ให้แผนดีกับคุณ

คุณสามารถชี้ไปsp_recompileที่โต๊ะหรือมุมมองได้ แต่จะเตือนล่วงหน้าว่าโค้ดทั้งหมดที่แตะกับตารางหรือมุมมองนั้นจะคอมไพล์ใหม่ นี่อาจทำให้ปัญหาหนักขึ้นทั้งหมด

ถ้ามันเป็นพารามิเตอร์การสืบค้น

งานของคุณยากขึ้นอีกหน่อย คุณจะต้องติดตาม SQL Handle คุณไม่ต้องการเพิ่มทั้งแผนแคช - เช่นเดียวsp_recompileกับการใช้กับตารางหรือมุมมองคุณสามารถทริกเกอร์ผลที่ไม่ได้ตั้งใจทั้งหมดได้ (ฮ่าฮ่าฮ่า)

วิธีที่ง่ายที่สุดในการคิดคำสั่งนั้นคือการรันsp_BlitzWho *! มีคอลัมน์ชื่อ "แก้ไขพารามิเตอร์การดมกลิ่น" ที่มีคำสั่งให้ลบแผนเดียวออกจากแคช สิ่งนี้มีข้อเสียเหมือนกับการคอมไพล์ซ้ำ

สิ่งนี้จะไม่แก้ไข:

  • กระบวนการกำลังทำงานอยู่

สิ่งนี้ไม่รับประกัน:

  • กระบวนการถัดไปที่รันหลังจากการคอมไพล์ใหม่จะใช้พารามิเตอร์ที่ให้แผนดีกับคุณ

ฉันยังต้องการความช่วยเหลือ!

เราจะต้องการสิ่งต่อไปนี้:

  • แผนแบบสอบถามที่ดีถ้าเป็นไปได้
  • แผนแบบสอบถามไม่ดี
  • พารามิเตอร์ที่ใช้
  • แบบสอบถามในคำถาม
  • นิยามตารางและดัชนี

รับแผนแบบสอบถามและแบบสอบถาม

หากแบบสอบถามกำลังทำงานคุณสามารถใช้sp_BlitzWho * หรือsp_WhoIsActiveเพื่อดักจับการสืบค้นที่ดำเนินการอยู่ในปัจจุบัน

EXEC sp_BlitzWho;

EXEC sp_WhoIsActive @get_plans = 1;

ถั่ว

หากแบบสอบถามไม่ได้ดำเนินการอยู่ในปัจจุบันคุณสามารถตรวจสอบได้ในแคชแผนโดยใช้sp_BlitzCache *

หากคุณใช้ SQL Server 2016+ และเปิด Query Store ไว้คุณสามารถใช้sp_BlitzQueryStore *

EXEC dbo.sp_BlitzCache @StoredProcName = 'Your Mom';

EXEC dbo.sp_BlitzQueryStore @StoredProcName = 'Your Mom';

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

EXEC dbo.sp_BlitzCache @QueryFilter = 'statement';

คุณควรเห็นผลลัพธ์ที่ค่อนข้างคล้ายกันจากสิ่งเหล่านั้น อีกครั้งแผนแบบสอบถามที่เชิญคอลัมน์ clicky สีน้ำเงินเจ๋ง ๆ คือเพื่อนของคุณ

ถั่ว

วิธีที่ง่ายที่สุดในการแบ่งปันแผนคือการใช้วาง The Plan * หรือทิ้ง XML ลงใน Pastebin หากต้องการรับสิ่งนั้นให้คลิกที่หนึ่งในคอลัมน์ที่มีการคลิกสีน้ำเงินเชิญชวน แผนคิวรีของคุณควรปรากฏในแท็บ SSMS ใหม่

ถั่ว

หากคุณใจแคบเกี่ยวกับการแบ่งปันรหัสและแบบสอบถามของ บริษัท คุณสามารถใช้เครื่องมือ Plan Explorer ฟรีของ Sentry Oneเพื่อลบล้างแผนของคุณ โปรดทราบว่าสิ่งนี้จะช่วยให้รับความช่วยเหลือได้ยากขึ้น - รหัสที่ไม่ระบุชื่อเป็นสิ่งที่อ่านและเข้าใจได้ยาก

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

การรับพารามิเตอร์นั้นยากขึ้นอีกเล็กน้อย หากคุณใช้Plan Explorerมีแท็บที่ด้านล่างซึ่งแสดงรายการทั้งหมดให้คุณ

ถั่ว

หากคุณใช้sp_BlitzCache * จะมีคอลัมน์ที่สามารถคลิกได้ซึ่งจะให้คำสั่งดำเนินการสำหรับขั้นตอนการจัดเก็บ

ถั่ว

รับนิยามตารางและดัชนี

คุณสามารถคลิกขวาใน SSMS เพื่อเขียนสคริปต์ได้อย่างง่ายดาย

ถั่ว

หากคุณต้องการได้ทุกอย่างในนัดเดียวsp_BlitzIndex * สามารถช่วยได้ถ้าคุณชี้ตรงไปที่โต๊ะ

EXEC dbo.sp_BlitzIndex @DatabaseName = 'StackOverflow2010',
                       @SchemaName = 'dbo',
                       @TableName = 'Users';

สิ่งนี้จะให้คำจำกัดความของตาราง (แม้ว่าจะไม่ใช่คำสั่งสร้าง) และสร้างคำสั่งสำหรับดัชนีทั้งหมดของคุณ

การรวบรวมและเพิ่มข้อมูลนี้ในคำถามของคุณควรช่วยให้ผู้คนมีข้อมูลเพียงพอที่จะช่วยเหลือหรือชี้แนะคุณในทิศทางที่ถูกต้อง

ฉันอยากทำเอง!

ดีเยี่ยม ฉันดีใจกับคุณด้วย. คุณเป็นคนบ้า

มีหลายวิธีที่ผู้คนคิดว่าพวกเขา "แก้ไข" การดมกลิ่นพารามิเตอร์:

แต่สิ่งเหล่านี้จริงๆเพียงปิดการใช้งานการดมพารามิเตอร์ในวิธีที่ต่างกัน นั่นไม่ได้หมายความว่าพวกเขาไม่สามารถแก้ปัญหาได้ แต่พวกเขาไม่เข้าใจสาเหตุที่แท้จริง

นั่นเป็นเพราะการไปถึงต้นเหตุมักเป็นเรื่องยาก คุณต้องมองหา "ปัญหาคุณภาพแผน" ที่น่ารำคาญ

เริ่มต้นด้วยแผนช้าและช้าค้นหาความแตกต่างเช่น:

  • ดัชนีที่ใช้
  • เข้าร่วมเพื่อ
  • อนุกรมเทียบกับขนาน

มองหาผู้ให้บริการที่แตกต่างกันซึ่งทำให้รหัสของคุณไวต่อการดมกลิ่นพารามิเตอร์:

  • การค้นหา
  • ทุกประเภท
  • เข้าร่วมประเภท
  • หน่วยความจำให้ (และโดยการขยายรั่วไหล)
  • สิ่งของ

อย่าสับสนกับการค้นหา vs scan การแตกตัวของดัชนีหรือสิ่งที่ผู้คนเชื่อมั่นในสินค้า

โดยปกติจะมีปัญหาในการทำดัชนีเบื้องต้น บางครั้งรหัสต้องการการเขียนใหม่เล็กน้อย

หากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการดมกลิ่นพารามิเตอร์:

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



28

การดมพารามิเตอร์ไม่ได้เป็นเพียงสาเหตุที่เป็นไปได้สำหรับประสิทธิภาพที่แตกต่างกันของแบบสอบถาม สาเหตุทั่วไปต่อไปนี้อาจแสดงอาการเดียวกัน:

  1. การกระจายข้อมูล / ปริมาณเปลี่ยนแปลงข้ามจุดเปลี่ยนโครงสร้างการค้นหาต้นไม้ของเครื่องมือเพิ่มประสิทธิภาพ
  2. ดัชนี / ไฟล์มีการแยกส่วน
  3. สถิติได้รับการปรับปรุง / เพิ่ม / ลดลงหรือกลายเป็นข้อมูลเก่าและทำให้เข้าใจผิดเนื่องจากการเปลี่ยนแปลงข้อมูล
  4. การใช้งานหน่วยความจำ Windows เปลี่ยนไป
  5. บันทึกธุรกรรมเต็มและไม่ตัดทอนทำให้เกิดการขยายไฟล์จริงซ้ำ
  6. เปลี่ยนสคีมาแล้ว - เพิ่มดัชนี / มุมมอง / คอลัมน์ / ข้อ จำกัด เพิ่มแก้ไขหรือลดลงเปลี่ยนประเภทข้อมูล ฯลฯ
  7. เปลี่ยนการตั้งค่าสถานะการสืบค้นกลับแล้ว
  8. ใช้การปรับปรุง Windows
  9. เปลี่ยนการตั้งค่าฐานข้อมูลหรือเซิร์ฟเวอร์แล้ว
  10. เปลี่ยนระดับ CU ของเซิร์ฟเวอร์แล้ว
  11. เปลี่ยนการตั้งค่าเซสชันแอปพลิเคชันไคลเอนต์

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


1
ขอบคุณสำหรับการแก้ไข Paul @sp_BlitzErik - มันไม่ใช่ความตั้งใจของฉันที่จะให้คำแนะนำในหัวข้อเฉพาะเพียงเพื่อสร้างความตระหนักว่าพวกเขามีอยู่และอาจคุ้มค่าที่จะตรวจสอบ นี่ไม่ได้หมายความว่าจะลดลงจากการโพสต์ที่ยอดเยี่ยมของคุณ คุณจัดการกับพารามิเตอร์การดมในเชิงลึกอย่างมืออาชีพและมีอารมณ์ขันดี ฉันสนุกกับการอ่าน ฉันเพียงต้องการให้แน่ใจว่าหากมีคนที่นี่เยี่ยมชมโพสต์นี้ตามชื่อลวงเขา / เธอจะทำให้ตระหนักถึงสาเหตุที่เป็นไปได้อื่น IMHO ช่วยเพิ่มมูลค่าให้กับโพสต์ของคุณ แต่หากคุณยังต้องการให้ฉันลบออกโปรดแจ้งให้เราทราบ
SQLRaptor

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

10

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

  • แบบแผนสำหรับตารางที่ใช้มีการเปลี่ยนแปลงตั้งแต่ครั้งสุดท้ายหรือไม่? ในกรณีของ SSMS คุณสามารถคลิกขวาที่เซิร์ฟเวอร์ในวัตถุ Explorer Reports → Standard Reports → Schema Changes Historyและเลือก
  • จำนวนรายการเพิ่มขึ้นอย่างรวดเร็วหรือไม่? บางทีคำค้นหาของคุณอาจช้ากว่านี้มากเมื่อมีข้อมูลจำนวนมากในตารางที่ใช้
  • มีคนอื่นใช้ฐานข้อมูลในเวลาเดียวกันกับคุณหรือไม่? อาจเลือกช่วงเวลาที่คุณไม่เข้าไปยุ่งกับงานของกันและกัน
  • สถิติของระบบเป็นอย่างไร บางทีเซิร์ฟเวอร์กำลังทำงานหนักและกำลังเร่งซีพียูหรือฮาร์ดไดรฟ์กำลังหมดพื้นที่หรือสลับ อาจมีปัญหาฮาร์ดแวร์อื่นเช่นไฟไหม้หรือน้ำท่วมในห้องเซิร์ฟเวอร์

7

ความเป็นไปได้อีกอย่างหนึ่งคือทีมโครงสร้างพื้นฐานของคุณกำลังใช้เครื่องมือเช่น vMotion บน VMware และ VM ที่สนับสนุนอินสแตนซ์ SQL ของคุณกำลังถูกย้ายจากโฮสต์ไปยังโฮสต์อย่างต่อเนื่องโดยที่ DBA ไม่ทราบ

นี่เป็นปัญหาที่แท้จริงเมื่อโครงสร้างพื้นฐานของคุณไม่มีที่มา ... ฉันมีฝันร้ายกับมัน

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