ในขณะที่ฉันเคารพผู้ส่งฉันไม่เห็นด้วยอย่างนอบน้อมกับคำตอบที่ให้และไม่ใช่ "เหตุผลทางศาสนา" ในคำอื่น ๆ ฉันเชื่อว่าไม่มีสิ่งอำนวยความสะดวกที่ Microsoft ได้ให้ไว้ซึ่งลดความต้องการคำแนะนำในการใช้ขั้นตอนการจัดเก็บ
คำแนะนำใด ๆ ที่มอบให้กับนักพัฒนาที่สนับสนุนการใช้ข้อความ SQL ดิบจะต้องเต็มไปด้วยคำเตือนมากมายเช่นที่ฉันคิดว่าคำแนะนำที่รอบคอบที่สุดคือการส่งเสริมการใช้วิธีการจัดเก็บอย่างมากและกีดกันทีมนักพัฒนาของคุณจากการฝึกปฏิบัติ ของการฝังคำสั่ง SQL ในรหัสหรือการส่งคำขอ SQL แบบข้อความธรรมดาที่ไม่ใช่แบบดั้งเดิมนอก SQL SPROC (ขั้นตอนการจัดเก็บ)
ฉันคิดว่าคำตอบง่ายๆสำหรับคำถามที่ว่าทำไมการใช้ SPROC จึงเป็นเหมือนผู้ส่งที่คาดเดา: SPROC จะได้รับการแยกวิเคราะห์ปรับให้เหมาะสมและเรียบเรียง ดังนั้นแผนแบบสอบถาม / การดำเนินการของพวกเขาจะถูกเก็บไว้เพราะคุณได้บันทึกการเป็นตัวแทนของแบบสอบถามและคุณโดยทั่วไปจะแตกต่างกันไปตามพารามิเตอร์เท่านั้นซึ่งไม่เป็นความจริงในกรณีของคำสั่ง SQL ที่คัดลอก / วางซึ่งอาจ morph จากหน้าต่อหน้าและส่วนประกอบ / ระดับและมักจะแปรปรวนในขอบเขตที่ตารางที่แตกต่างกันแม้ชื่อฐานข้อมูลสามารถระบุได้จากการโทรเพื่อโทร การอนุญาตเฉพาะกิจแบบนี้การส่ง SQL ช่วยลดโอกาสที่ DB Engine จะใช้แผนคิวรีสำหรับคำสั่งเฉพาะกิจของคุณอีกครั้งตามกฎที่เข้มงวดมาก ที่นี่ฉันกำลังสร้างความแตกต่างระหว่างแบบสอบถามเฉพาะกิจแบบไดนามิก (ในจิตวิญญาณของคำถามขึ้น) กับการใช้ระบบที่มีประสิทธิภาพ SPROC sp_executesql
โดยเฉพาะอย่างยิ่งมีองค์ประกอบดังต่อไปนี้:
- แผนเคียวรีแบบขนานและแบบขนานที่ไม่เก็บบริบทผู้ใช้และอนุญาตให้นำมาใช้ใหม่โดยเอ็นจิน DB
- บริบทการดำเนินการที่ช่วยให้สามารถใช้แผนคิวรีซ้ำโดยผู้ใช้ใหม่ที่มีพารามิเตอร์ข้อมูลต่างกัน
- โพรซีเดอร์แคชซึ่งเป็นสิ่งที่เอ็นจิ้น DB สอบถามเพื่อสร้างประสิทธิภาพที่เราค้นหา
เมื่อคำสั่ง SQL ออกจากหน้าเว็บเรียกว่า "คำสั่ง ad hoc" เอ็นจิ้นจะค้นหาแผนการดำเนินการที่มีอยู่เพื่อจัดการกับคำขอ เนื่องจากนี่คือข้อความที่ส่งมาจากผู้ใช้จึงจะถูกนำเข้าไปวิเคราะห์แยกวิเคราะห์และประมวลผลหากมันถูกต้อง ในเวลานี้จะได้รับค่าใช้จ่ายแบบสอบถามเป็นศูนย์ ค่าใช้จ่ายแบบสอบถามจะใช้เมื่อเอ็นจิน DB ใช้อัลกอริธึมเพื่อกำหนดว่าแผนปฏิบัติการใดที่จะขับไล่จากแคช
คำสั่งเฉพาะกิจจะได้รับค่าใช้จ่ายการสืบค้นดั้งเดิมเป็นศูนย์โดยค่าเริ่มต้น เมื่อมีการประมวลผลข้อความคิวรีเฉพาะกิจที่เหมือนกันในภายหลังโดยกระบวนการของผู้ใช้อื่น (หรือข้อความเดียวกัน) ต้นทุนการสืบค้นปัจจุบันจะถูกรีเซ็ตเป็นต้นทุนการคอมไพล์ดั้งเดิม เนื่องจากค่าใช้จ่ายในการรวบรวมแบบสอบถามเฉพาะกิจของเราเป็นศูนย์สิ่งนี้จึงไม่ดีสำหรับความเป็นไปได้ที่จะนำมาใช้ซ้ำ เห็นได้ชัดว่าศูนย์เป็นจำนวนเต็มน้อยที่สุด แต่ทำไมมันจะถูกขับไล่?
เมื่อเกิดแรงกดดันหน่วยความจำและพวกเขาจะทำถ้าคุณมีไซต์ที่ใช้งานบ่อยเอ็นจิ้น DB ใช้อัลกอริทึมการล้างข้อมูลเพื่อกำหนดวิธีที่จะสามารถเรียกคืนหน่วยความจำที่แคชขั้นตอนใช้อยู่ มันใช้ต้นทุนการสืบค้นปัจจุบันเพื่อตัดสินใจว่าจะขับไล่แผนการใด อย่างที่คุณอาจเดาได้ว่าแผนที่มีค่าศูนย์เป็นคนแรกที่ถูกขับไล่ออกจากแคชเพราะศูนย์หมายถึง "ไม่มีผู้ใช้ปัจจุบันหรืออ้างอิงถึงแผนนี้"
- หมายเหตุ: แผนปฏิบัติการ Ad Hoc - ค่าใช้จ่ายปัจจุบันจะเพิ่มขึ้นตามกระบวนการของผู้ใช้แต่ละรายโดยต้นทุนดั้งเดิมของแผน อย่างไรก็ตามไม่มีค่าใช้จ่ายสูงสุดของแผนสามารถมากกว่าต้นทุนการคอมไพล์ดั้งเดิม ... ในกรณีของแบบสอบถามเฉพาะกิจ ... ศูนย์ ดังนั้นมันจะ "เพิ่มขึ้น" ตามมูลค่านั้น ... ศูนย์ - ซึ่งหมายความว่ามันจะยังคงเป็นแผนต้นทุนที่ต่ำที่สุด
ดังนั้นจึงค่อนข้างเป็นไปได้ที่แผนดังกล่าวจะถูกขับไล่ก่อนเมื่อเกิดความกดดันจากหน่วยความจำ
ดังนั้นหากคุณมีเซิร์ฟเวอร์ที่มีหน่วยความจำมากมาย "เกินความต้องการของคุณ" คุณอาจไม่ประสบปัญหานี้บ่อยเท่าเซิร์ฟเวอร์ไม่ว่างที่มีหน่วยความจำ "เพียงพอ" เท่านั้นที่จะจัดการกับภาระงานได้ (ขออภัยความจุหน่วยความจำของเซิร์ฟเวอร์และการใช้งานค่อนข้างเป็นส่วนตัว / สัมพัทธ์แม้ว่าอัลกอริทึมจะไม่)
ตอนนี้ถ้าฉันไม่ถูกต้องจริงเกี่ยวกับหนึ่งหรือหลายจุดฉันแน่นอนเปิดให้แก้ไข
สุดท้ายผู้เขียนเขียนว่า:
"ตอนนี้เรามีการเพิ่มประสิทธิภาพระดับคำสั่งดังนั้นการค้นหาพารามิเตอร์ที่เหมาะสมที่มาจากแอปพลิเคชันสามารถใช้ประโยชน์จากแผนการดำเนินการเดียวกันกับแบบสอบถามที่ฝังอยู่ในกระบวนงานที่เก็บไว้"
ฉันเชื่อว่าผู้เขียนอ้างถึงตัวเลือก "เพิ่มประสิทธิภาพสำหรับปริมาณงานเฉพาะกิจ"
ถ้าเป็นเช่นนั้นตัวเลือกนี้จะช่วยให้กระบวนการสองขั้นตอนซึ่งหลีกเลี่ยงการส่งแผนแบบสอบถามแบบเต็มไปยังแคชขั้นตอนทันที มันจะส่งแบบสอบถามที่เล็กลงเท่านั้นที่มี หากการสอบถามที่แน่นอนถูกส่งกลับไปที่เซิร์ฟเวอร์ในขณะที่การสอบถามแบบสอบถามยังคงอยู่ในขั้นตอนการแคชแผนดำเนินการแบบสอบถามแบบเต็มจะถูกบันทึกลงในขั้นตอนการแคชในเวลานั้น สิ่งนี้จะบันทึกในหน่วยความจำซึ่งในระหว่างเกิดเหตุการณ์ความดันหน่วยความจำอาจทำให้อัลกอริทึมการขับไล่สามารถขับส่วนที่เหลือของคุณน้อยกว่าแผนคิวรีขนาดใหญ่ที่ถูกแคช อีกครั้งนี้ขึ้นอยู่กับหน่วยความจำเซิร์ฟเวอร์และการใช้ประโยชน์
อย่างไรก็ตามคุณต้องเปิดตัวเลือกนี้เนื่องจากจะปิดไว้ตามค่าเริ่มต้น
สุดท้ายฉันต้องการเน้นว่าบ่อยครั้งที่นักพัฒนาเหตุผลอย่างมากจะฝัง SQL ลงในหน้าส่วนประกอบและที่อื่น ๆ เพราะพวกเขาต้องการที่จะมีความยืดหยุ่นและส่งแบบสอบถาม SQL แบบไดนามิกไปยังโปรแกรมฐานข้อมูล ดังนั้นในกรณีการใช้งานจริงการส่งข้อความเดียวกันการโทรข้ามสายจึงไม่น่าจะเกิดขึ้นเช่นเดียวกับการแคช / ประสิทธิภาพที่เราค้นหาเมื่อส่งแบบสอบถามเฉพาะกิจไปยัง SQL Server
สำหรับข้อมูลเพิ่มเติมโปรดดู:
https://technet.microsoft.com/en-us/library/ms181055(v=sql.105).aspx
http://sqlmag.com/database-performance-tuning/don-t-fear-dynamic-sql
ดีที่สุด
เฮนรี่