ฉันมีแบบสอบถามด้านล่าง:
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
แบบสอบถามด้านบนเสร็จสมบูรณ์ในสามวินาที
หากเคียวรีด้านบนคืนค่าใด ๆ เราต้องการให้โพรซีเดอร์ที่เก็บไว้เป็น EXIT ดังนั้นฉันจึงเขียนมันใหม่ด้านล่าง:
If Exists(
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
)
Begin
Raiserror('Source missing',16,1)
Return
End
อย่างไรก็ตามการดำเนินการนี้ใช้เวลา 10 นาที
ฉันสามารถเขียนข้อความค้นหาด้านบนเหมือนด้านล่างซึ่งเสร็จสมบูรณ์ในเวลาน้อยกว่า 3 วินาที:
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source
if @@rowcount >0
Begin
Raiserror('Source missing',16,1)
Return
End
ปัญหาเกี่ยวกับการเขียนซ้ำข้างต้นคือแบบสอบถามข้างต้นเป็นส่วนหนึ่งของขั้นตอนการจัดเก็บที่ใหญ่กว่าและส่งคืนชุดผลลัพธ์หลายชุด ใน C # เราวนซ้ำแต่ละชุดผลลัพธ์และทำการประมวลผลบางอย่าง
ด้านบนส่งคืนชุดผลลัพธ์ที่ว่างเปล่าดังนั้นถ้าฉันไปด้วยวิธีนี้ฉันต้องเปลี่ยน C # ของฉันและทำการปรับใช้อีกครั้ง
ดังนั้นคำถามของฉันคือ
เหตุใดการใช้เพียง
IF EXISTS
เปลี่ยนแผนเพื่อใช้เวลามาก
ด้านล่างนี้เป็นรายละเอียดที่อาจช่วยคุณและแจ้งให้เราทราบหากคุณต้องการรายละเอียดใด ๆ :
- สร้างตารางและสคริปต์สถิติเพื่อรับแผนเดียวกับของฉัน
- แผนปฏิบัติการช้า
แผนปฏิบัติการที่รวดเร็ว
แผนช้าโดยใช้ Brentozar วางแผนแผน
รวดเร็วโดยใช้ Brentozar วางแผน
หมายเหตุ:ข้อความค้นหาทั้งสองเหมือนกัน (ใช้พารามิเตอร์) ความแตกต่างเพียงอย่างเดียวคือEXISTS
(ฉันอาจทำผิดพลาดบางอย่างในขณะที่ไม่ระบุตัวตน)
สคริปต์การสร้างตารางอยู่ด้านล่าง:
http://pastebin.com/CgSHeqXc - สถิติตารางขนาดเล็ก
http://pastebin.com/GUu9KfpS - สถิติตารางขนาดใหญ่