รหัสจะสร้างแผนที่แตกต่างเมื่อเรียกใช้ Ad-hoc เทียบกับในขั้นตอนการจัดเก็บ


9

ฉันมีคำสั่งลบที่ใช้แผนไม่ดีเมื่อเรียกใช้ภายในกระบวนงานที่เก็บไว้ แต่เลือกแผนที่ดีกว่ามากเมื่อเรียกใช้โฆษณา

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

ฉันต้องการทราบว่าเพราะเหตุใดเครื่องมือเพิ่มประสิทธิภาพใช้แผนการดำเนินการที่แตกต่างกันสำหรับขั้นตอนการจัดเก็บเทียบกับ ad-hoc SQL

UPDATE: ฉันเดาว่ามันต้องเป็นพารามิเตอร์หลังจากทั้งหมด - เมื่อฉันรันโค้ด ad-hoc พร้อมตัวแปร hardcoded ฉันสามารถรับแผน "ไม่ดี" ด้วยค่าที่ถูกต้อง (เป็นวันที่ค่าที่มีอายุหนึ่งปี ดูเหมือนจะสร้างแผน "ดี") ตอนนี้พยายามบังคับแผน "ดี" ใน proc โดยใช้คำใบ้แบบสอบถาม

การแก้ไข: ฉันสิ้นสุดการรับแผนที่ฉันต้องการโดยใช้คำแนะนำที่เหมาะสมที่สุดสำหรับคำใบ้ที่ไม่รู้จัก


มันอาจจะพารามิเตอร์ดมกลิ่น แบบสอบถามใช้อ้างอิงตัวแปรWHEREตามข้อหรือไม่?
Nick Chammas

4
คุณสามารถเพิ่มรหัสโปรด
GBN

โปรดโพสต์แผนบางแห่งด้วย อย่างที่บอกไปแล้วว่าทำไมแผนถึงแตกต่าง
Aaron Bertrand

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

แผนสำหรับโค้ด ad-hoc (ดี) ทำการสแกนตารางของตารางเล็ก ๆ (ซึ่งมีเพียง 5-10 แถว) และใช้ดัชนีที่ไม่ใช่คลัสเตอร์ของตารางขนาดใหญ่เพื่อค้นหาแถวที่จำเป็นต้องตรวจสอบใน PK ของตารางขนาดใหญ่ ฉันจะพยายามทำให้แผนที่แท้จริงเกิดขึ้นเร็วที่สุดเท่าที่จะทำได้
msgisme

คำตอบ:


5

ผู้ต้องสงสัยปกติ:

  1. ค่าคงที่ใน adhoc พารามิเตอร์ในรหัส
  2. ชนิดข้อมูลไม่ตรงกันในรหัส
  3. การดมกลิ่นพารามิเตอร์

จุดที่ 1: เครื่องมือเพิ่มประสิทธิภาพสามารถเลือกแผนการที่ดีที่สุดสำหรับค่าคงที่
เปลี่ยนค่าคงที่ = เปลี่ยนแผน ชุดค่าพารามิเตอร์ที่กำหนดนั้นสามารถ resuable ได้

จุดที่ 2 จะแนะนำการแปลงโดยนัยเนื่องจากความสำคัญของประเภทข้อมูล
เช่นคอลัมน์ varchar เปรียบเทียบกับพารามิเตอร์ nvarchar

จุดที่ 3: ใช้การปิดบังพารามิเตอร์หรือเพิ่มประสิทธิภาพสำหรับ UNKNOWN
แก้ไข: เพื่อทดสอบ: รัน proc ที่จัดเก็บไว้ให้รัน sp_updatestats รันอีกครั้ง การทำเช่นนี้จะทำให้แผนการแคชซึ่งทำให้การล้างแคชของแผนดีขึ้น

แก้ไข: หลังจากความคิดเห็นของ jcolebrand

คุณสามารถปิดการดมกลิ่นได้หลายวิธี 3 หลักคือ

  • RECOMPILE นี่คือ IMO ที่ไร้สาระ
  • เพิ่มประสิทธิภาพ (sic) สำหรับ UNKNOWN
  • การปิดบังพารามิเตอร์

การปิดบังพารามิเตอร์:

DECLARE @MaskedParam varchar(10)
SELECT @MaskedParam = @SignaureParam

SELECT...WHERE column = @MaskedParam

การปิดบังและการเพิ่มประสิทธิภาพคำใบ้มีผลเหมือนกัน (อาจเป็นเพราะเหตุผลต่าง ๆ ) กล่าวคือเครื่องมือเพิ่มประสิทธิภาพต้องใช้สถิติและการกระจายข้อมูล ( หมายเหตุ: ยังอยู่ภายใต้การทดสอบโดย Mark Storey-Smith ) ประเมินพารามิเตอร์ด้วยข้อดีของตัวเองหรือไม่ แทนที่จะเป็นสายสุดท้าย เครื่องมือเพิ่มประสิทธิภาพสามารถคอมไพล์ใหม่หรือไม่ SQL Server 2005 เพิ่มการคอมไพล์ระดับคำสั่งใหม่ดังนั้นจึงมีผลกระทบน้อยกว่า

ตอนนี้ทำไมแผนที่มีพารามิเตอร์ "ดม" เป็น "เหนียว" เมื่อเทียบกับพารามิเตอร์หลอกลวง / "ไม่ทราบ" ฉันไม่แน่ใจ

ฉันใช้การปิดบังพารามิเตอร์ตั้งแต่ SQL Server 2000 ทั้งหมด แต่เป็นรหัสที่ง่ายที่สุด ฉันสังเกตว่ามันจะเกิดขึ้นกับรหัสที่ซับซ้อนมากขึ้น และที่งานเก่าของฉันฉันมีโปรแกรมรายงานบางตัวที่ฉันสามารถเปลี่ยนค่าเริ่มต้นของพารามิเตอร์แผนได้ ฉันคิดว่าวิธีการ "ขนส่งสินค้าทางศาสนา" นั้นง่ายกว่าการขอความช่วยเหลือ

แก้ไข 2, 12 ต.ค. 2554, หลังการแชท

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

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

  • บทความ MS Connect นี้เป็นเรื่องที่น่าสนใจ: การใช้ดัชนีที่ไม่น่าสนใจภายในกระบวนงานที่เก็บไว้ (กล่าวถึงในคำตอบ SO ด้านล่าง)

  • Bob Beauchemin พูดถึงมันด้วย

ปัญหาที่โดดเด่น

  • การดมกลิ่นยังคงใช้กับ RECOMPILE หรือไม่ นั่นคือถ้าเครื่องมือเพิ่มประสิทธิภาพรู้ว่าจะทิ้งแผนมันมีจุดมุ่งหมายเพื่อนำกลับมาใช้ใหม่หรือไม่?

  • เพราะเหตุใดแผนจึงดมกลิ่น "เหนียว"?

ลิงก์จาก SO:


1. พารามิเตอร์ใน sp เป็นตัวแปรในรหัส 2 อีกครั้งประเภทข้อมูลเดียวกัน 3. ฉันได้ใช้ทั้งพารามิเตอร์ที่หลากหลายและฉันได้รับแผนเดียวกันทุกครั้ง ฉันล้างแคชหลังจากพยายามแต่ละครั้ง
msgisme

1
Re: จุด 3 คุณยังสามารถเรียกใช้คำสั่งด้วยOPTION (RECOMPILE)หรือทั้ง proc WITH RECOMPILEเพื่อบังคับให้ SQL Server ไม่สนใจแผนที่มีอยู่
Nick Chammas

3
BTW เป็นOPTIMIZEเพราะ Microsoft เป็น บริษัท อเมริกัน :)
Nick Chammas

1
@Gbn มีความคิดเกี่ยวกับการป้องกัน / การเอาชนะการดมกลิ่นพารามิเตอร์?
jcolebrand

1
@ jcolebrand: คำตอบง่ายๆคือ "ไม่" :-)
gbn

2

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

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