มีข้อความค้นหาที่เมื่อเรากด "execute" มันจะแสดงบางแถวและมันจะเพิ่มขึ้นเรื่อย ๆ แต่แบบสอบถามนั้นยังไม่จบ แต่บางครั้งมันจะรอจนกว่าจะสิ้นสุดการสืบค้น
ทำไมสิ่งนี้ถึงเกิดขึ้น มีวิธีควบคุมสิ่งนี้หรือไม่?
มีข้อความค้นหาที่เมื่อเรากด "execute" มันจะแสดงบางแถวและมันจะเพิ่มขึ้นเรื่อย ๆ แต่แบบสอบถามนั้นยังไม่จบ แต่บางครั้งมันจะรอจนกว่าจะสิ้นสุดการสืบค้น
ทำไมสิ่งนี้ถึงเกิดขึ้น มีวิธีควบคุมสิ่งนี้หรือไม่?
คำตอบ:
คำตอบตามปกติ (ไม่เป็นไรเวลาส่วนใหญ่) อยู่ในแผนการดำเนินการ
มีโอเปอเรเตอร์บางตัวที่ต้องการให้ทุกแถวมาถึงพวกมันก่อนที่พวกเขาจะสามารถเริ่มการประมวลผลแถวเหล่านั้นและส่งพวกมันแบบดาวน์สตรีมเช่น:
พวกเขากำลังเรียกว่าการบล็อกหรือหยุดและดำเนินการไปเพราะสิ่งนี้และพวกเขามักจะถูกเลือกเมื่อเครื่องมือเพิ่มประสิทธิภาพคิดว่ามันจะต้องประมวลผลข้อมูลจำนวนมากเพื่อค้นหาข้อมูลของคุณ
มีโอเปอเรเตอร์อื่น ๆ ที่สามารถเริ่มการสตรีมหรือส่งผ่านแถวที่พบได้ทันที
เมื่อเคียวรีเริ่มส่งคืนข้อมูลทันที แต่ไม่เสร็จในทันทีโดยทั่วไปแล้วสัญญาณว่าเครื่องมือเพิ่มประสิทธิภาพเลือกแผนเพื่อค้นหาและส่งคืนแถวอย่างรวดเร็วโดยใช้โอเปอเรเตอร์ที่มีต้นทุนเริ่มต้นต่ำ
สิ่งนี้อาจเกิดขึ้นได้เพราะเป้าหมายของแถวแนะนำโดยคุณหรือจากเครื่องมือเพิ่มประสิทธิภาพ
นอกจากนี้ยังสามารถเกิดขึ้นได้หากเลือกแผนไม่ดีด้วยเหตุผลบางอย่าง (การขาดความสามารถในการ SARGability, การดมพารามิเตอร์, สถิติไม่เพียงพอ ฯลฯ ) แต่ก็ต้องใช้การขุดมากขึ้น
สำหรับข้อมูลเพิ่มเติมโปรดดูบล็อกของ Rob Farley ที่นี่
และซีรีส์พอลไวท์ในเป้าหมายแถวที่นี่ , ที่นี่ , ที่นี่และที่นี่
ควรสังเกตว่าถ้าคุณกำลังพูดถึง SSMS แถวจะปรากฏเฉพาะเมื่อบัฟเฟอร์เต็มแล้วเท่านั้นไม่ใช่เพียงความจำใจเท่านั้น
ถ้าฉันเข้าใจสิ่งที่คุณสังเกตนี่คือวิธีที่ Studio จัดการแสดงผลแถวและมีส่วนเกี่ยวข้องกับวิธีที่ SQL Server ส่งคืนแถว ในความเป็นจริงบ่อยครั้งเมื่อคุณส่งคืนผลลัพธ์ที่มีขนาดใหญ่ไปยัง SSMS และพยายามแสดงผลในตาราง SSMS ไม่สามารถติดตามได้และ SQL Server จะรอให้แอปประมวลผลแถวมากขึ้น ในกรณีนี้คุณจะเห็นการASYNC_NETWORK_IO
รอคอยของSQL Server
คุณสามารถควบคุมได้โดยใช้ Results to Text แทนที่จะเป็น Results to Grid เนื่องจาก SSMS สามารถวาดข้อความได้เร็วกว่าที่จะวาดกริด แต่คุณอาจพบว่าสิ่งนี้อาจส่งผลต่อการอ่านได้ขึ้นอยู่กับจำนวนคอลัมน์และประเภทข้อมูลที่เกี่ยวข้อง ทั้งสองอย่างได้รับผลกระทบจากเมื่อ SSMS ตัดสินใจที่จะเขียนผลลัพธ์ไปยังบานหน้าต่างนั้นขึ้นอยู่กับว่าบัฟเฟอร์เอาต์พุตเต็มขนาดใด
เมื่อคุณมีหลายชุดคำสั่งและคุณต้องการบังคับให้บัฟเฟอร์แสดงผลผลลัพธ์ไปยังบานหน้าต่างข้อความคุณสามารถใช้เคล็ดลับการพิมพ์เล็กน้อยระหว่างคำสั่ง:
RAISERROR('', 0, 1) WITH NOWAIT;
แต่สิ่งนี้จะไม่ช่วยเมื่อคุณพยายามทำให้ SSMS แสดงแถวได้เร็วขึ้นเมื่อเอาต์พุตทั้งหมดมาจากคำสั่งเดียว
ยิ่งไปกว่านั้นคุณสามารถควบคุมได้โดย จำกัด จำนวนผลลัพธ์ที่คุณแสดงผลใน SSMS ฉันมักจะเห็นคนบ่นว่าต้องใช้เวลานานแค่ไหนในการส่งคืนล้านแถวไปยังกริด ใครในโลกนี้จะทำอะไรกับล้านแถวในตาราง SSMS ฉันไม่มีความคิด
มีแฮ็กบางอย่างOPTION (FAST 100)
ที่จะปรับให้เหมาะสำหรับการเรียก 100 แถวแรกเหล่านั้น (หรือ 100 แถวใด ๆ หากไม่มีด้านนอกORDER BY
) แต่สิ่งนี้อาจทำให้เกิดการเรียกคืนได้ช้ากว่าสำหรับส่วนที่เหลือของแถวและแผนที่มีมากกว่า โดยรวมแล้วไม่มีประสิทธิภาพดังนั้นจึงไม่ใช่ตัวเลือกที่ใช้ในการไปที่ IMHO
คำถามของคุณไม่เกี่ยวกับ SQLServer ต่อ se แต่:
มีวิธีควบคุมสิ่งนี้หรือไม่?
คำตอบสั้น ๆ :
sqlcmd
แทนssms
หรือsqlcmd
- โหมดของssms
คำตอบยาว :
แน่นอน! แต่ไม่ได้หนึ่ง - prob
sqlcmd
หรือในsqlcmd
โหมดโหมดใน ssmsspid
และคุณจะได้รับรายการการตั้งค่าเซสชันทั้งหมด เปรียบเทียบกับการตั้งค่าของsqlcmd
เซสชัน หากไม่มีสิ่งใดคลิก - คัดลอกการตั้งค่าเซสชันทั้งหมดจากผู้สร้างโปรไฟล์ลงในสคริปต์การสืบค้นของคุณให้ดำเนินการในsqlcmd
โหมดและค่อยๆเปลี่ยนการตั้งค่าคุณจะพบผู้กระทำผิดโชคดี!
ในการเพิ่มคำตอบของ sp_BlitzErik ให้นำตัวอย่างโดยใช้ a NOT IN ()
พร้อมกับตัวเลือกย่อย เพื่อที่จะตรวจสอบว่ารายการนั้นเป็นผลของการสืบค้นซ้อนหรือไม่มันเป็น (โดยทั่วไป) ที่จำเป็นในการดึงผลลัพธ์ทั้งหมด
ดังนั้นวิธีที่ง่ายวิธีหนึ่งที่ฉันได้พบในการปรับปรุงประสิทธิภาพการทำงานของคำสั่งดังกล่าวคือการเขียนให้พวกเขาเป็นผู้LEFT OUTER JOIN
ที่มีที่เงื่อนไขRIGHT
ด้านเป็นโมฆะ (คุณสามารถพลิกมันไปรอบ ๆ แน่นอน แต่ที่ใช้RIGHT OUTER JOINS
?) สิ่งนี้จะช่วยให้ผลลัพธ์เริ่มกลับมาทันที
WHERE t.x IN (<complex SELECT subquery>)
, LEFT JOIN ที่เทียบเท่ากันLEFT JOIN (<complex SELECT subquery>) AS r ON r.x = t.x .... WHERE r.x IS NULL
แล้วแบบสอบถามย่อยจะได้รับการประเมินเช่นกัน (เช่นแผนซับซ้อนที่ไม่มี ในเวอร์ชัน)
NOT EXISTS
แต่ Oracle NOT IN
ในแบบสอบถาม แต่วันนี้ต้องถือว่าเป็นข้อผิดพลาดในตัวสร้างแผน