ฉันมีคลาสของคำถามที่ทดสอบการมีอยู่ของหนึ่งในสองสิ่งนี้ มันเป็นรูปแบบ
SELECT CASE
WHEN EXISTS (SELECT 1 FROM ...)
OR EXISTS (SELECT 1 FROM ...)
THEN 1 ELSE 0 END;
ข้อความจริงถูกสร้างขึ้นใน C และดำเนินการเป็นแบบสอบถามเฉพาะกิจผ่านการเชื่อมต่อ ODBC
เมื่อเร็ว ๆ นี้พบว่า SELECT ที่สองอาจเร็วกว่า SELECT แรกในกรณีส่วนใหญ่และการเปลี่ยนคำสั่งของสองประโยค EXISTS ทำให้เกิดการเร่งความเร็วอย่างมากในกรณีทดสอบที่ไม่เหมาะสมอย่างน้อยหนึ่งกรณีที่เราเพิ่งสร้างขึ้น
สิ่งที่ชัดเจนที่ต้องทำคือเดินหน้าต่อไปและสลับสองประโยค แต่ฉันต้องการดูว่ามีคนคุ้นเคยกับ SQL Server มากกว่านี้หรือไม่ รู้สึกเหมือนว่าฉันอาศัยความบังเอิญและ "รายละเอียดการนำไปปฏิบัติ"
(ดูเหมือนว่าถ้า SQL Server ฉลาดขึ้นก็จะดำเนินการทั้งสองข้อ EXISTS ในแบบคู่ขนานและปล่อยให้สิ่งใดสิ่งหนึ่งที่ทำให้เกิดการลัดวงจรเป็นครั้งแรก
มีวิธีที่ดีกว่าในการทำให้ SQL Server ปรับปรุงเวลาใช้งานของแบบสอบถามอย่างสม่ำเสมอหรือไม่?
ปรับปรุง
ขอบคุณสำหรับเวลาและความสนใจในคำถามของฉัน ฉันไม่ได้คาดหวังคำถามเกี่ยวกับแผนแบบสอบถามจริง แต่ฉันยินดีที่จะแบ่งปัน
สำหรับส่วนประกอบซอฟต์แวร์ที่รองรับ SQL Server 2008R2 ขึ้นไป รูปร่างของข้อมูลอาจแตกต่างกันมากขึ้นอยู่กับการกำหนดค่าและการใช้งาน เพื่อนร่วมงานของฉันคิดว่าจะทำการเปลี่ยนแปลงนี้กับแบบสอบถามเนื่องจากตาราง (ในตัวอย่าง) dbf_1162761$z$rv$1257927703จะมีจำนวนมากกว่าหรือเท่ากับจำนวนแถวในdbf_1162761$z$dd$1257927703ตารางนั้นมากกว่าตาราง - บางครั้งก็มีความหมายมากขึ้น (คำสั่งของขนาด)
นี่คือกรณีที่ไม่เหมาะสมที่ฉันพูดถึง แบบสอบถามแรกคือแบบสอบถามที่ช้าและใช้เวลาประมาณ 20 วินาที แบบสอบถามที่สองเสร็จสมบูรณ์ในทันที
สำหรับสิ่งที่คุ้มค่าบิต "เพิ่มประสิทธิภาพสำหรับ UNKNOWN" ก็ถูกเพิ่มเมื่อไม่นานมานี้ด้วยเนื่องจากการดมกลิ่นพารามิเตอร์กำลังทำลายบางกรณี
ข้อความค้นหาเดิม:
SELECT CASE
WHEN EXISTS (SELECT 1 FROM zumero.dbf_1162761$z$rv$1257927703 rv INNER JOIN zumero.dbf_1162761$t$tx tx ON tx.txid=rv.txid WHERE tx.generation BETWEEN 1500 AND 2502)
OR EXISTS (SELECT 1 FROM zumero.dbf_1162761$z$dd$1257927703 dd INNER JOIN zumero.dbf_1162761$t$tx tx ON tx.txid=dd.txid WHERE tx.generation BETWEEN 1500 AND 2502)
THEN 1 ELSE 0 END
OPTION (OPTIMIZE FOR UNKNOWN)
แผนเดิม:
|--Compute Scalar(DEFINE:([Expr1006]=CASE WHEN [Expr1007] THEN (1) ELSE (0) END))
|--Nested Loops(Left Semi Join, DEFINE:([Expr1007] = [PROBE VALUE]))
|--Constant Scan
|--Concatenation
|--Nested Loops(Inner Join, WHERE:([scale].[zumero].[dbf_1162761$z$rv$1257927703].[txid] as [rv].[txid]=[scale].[zumero].[dbf_1162761$t$tx].[txid] as [tx].[txid]))
| |--Clustered Index Scan(OBJECT:([scale].[zumero].[dbf_1162761$z$rv$1257927703].[PK__dbf_1162__97770A2F62EEAE79] AS [rv]), WHERE:([scale].[zumero].[dbf_1162761$z$rv$1257927703].[txid] as [rv].[txid]>(0)))
| |--Index Seek(OBJECT:([scale].[zumero].[dbf_1162761$t$tx].[gendex] AS [tx]), SEEK:([tx].[generation] >= (1500) AND [tx].[generation] <= (2502)) ORDERED FORWARD)
|--Nested Loops(Inner Join, OUTER REFERENCES:([tx].[txid]))
|--Clustered Index Scan(OBJECT:([scale].[zumero].[dbf_1162761$t$tx].[PK__dbf_1162__E3BA953EC2197789] AS [tx]), WHERE:([scale].[zumero].[dbf_1162761$t$tx].[generation] as [tx].[generation]>=(1500) AND [scale].[zumero].[dbf_1162761$t$tx].[generation] as [tx].[generation]<=(2502)) ORDERED FORWARD)
|--Index Seek(OBJECT:([scale].[zumero].[dbf_1162761$z$dd$1257927703].[n$dbf_1162761$z$dd$txid$1257927703] AS [dd]), SEEK:([dd].[txid]=[scale].[zumero].[dbf_1162761$t$tx].[txid] as [tx].[txid]), WHERE:([scale].[zumero].[dbf_1162761$z$dd$1257927703].[txid] as [dd].[txid]>(0)) ORDERED FORWARD)
ข้อความค้นหาคงที่:
SELECT CASE
WHEN EXISTS (SELECT 1 FROM zumero.dbf_1162761$z$dd$1257927703 dd INNER JOIN zumero.dbf_1162761$t$tx tx ON tx.txid=dd.txid WHERE tx.generation BETWEEN 1500 AND 2502)
OR EXISTS (SELECT 1 FROM zumero.dbf_1162761$z$rv$1257927703 rv INNER JOIN zumero.dbf_1162761$t$tx tx ON tx.txid=rv.txid WHERE tx.generation BETWEEN 1500 AND 2502)
THEN 1 ELSE 0 END
OPTION (OPTIMIZE FOR UNKNOWN)
แผนคงที่:
|--Compute Scalar(DEFINE:([Expr1006]=CASE WHEN [Expr1007] THEN (1) ELSE (0) END))
|--Nested Loops(Left Semi Join, DEFINE:([Expr1007] = [PROBE VALUE]))
|--Constant Scan
|--Concatenation
|--Nested Loops(Inner Join, OUTER REFERENCES:([tx].[txid]))
| |--Clustered Index Scan(OBJECT:([scale].[zumero].[dbf_1162761$t$tx].[PK__dbf_1162__E3BA953EC2197789] AS [tx]), WHERE:([scale].[zumero].[dbf_1162761$t$tx].[generation] as [tx].[generation]>=(1500) AND [scale].[zumero].[dbf_1162761$t$tx].[generation] as [tx].[generation]<=(2502)) ORDERED FORWARD)
| |--Index Seek(OBJECT:([scale].[zumero].[dbf_1162761$z$dd$1257927703].[n$dbf_1162761$z$dd$txid$1257927703] AS [dd]), SEEK:([dd].[txid]=[scale].[zumero].[dbf_1162761$t$tx].[txid] as [tx].[txid]), WHERE:([scale].[zumero].[dbf_1162761$z$dd$1257927703].[txid] as [dd].[txid]>(0)) ORDERED FORWARD)
|--Nested Loops(Inner Join, WHERE:([scale].[zumero].[dbf_1162761$z$rv$1257927703].[txid] as [rv].[txid]=[scale].[zumero].[dbf_1162761$t$tx].[txid] as [tx].[txid]))
|--Clustered Index Scan(OBJECT:([scale].[zumero].[dbf_1162761$z$rv$1257927703].[PK__dbf_1162__97770A2F62EEAE79] AS [rv]), WHERE:([scale].[zumero].[dbf_1162761$z$rv$1257927703].[txid] as [rv].[txid]>(0)))
|--Index Seek(OBJECT:([scale].[zumero].[dbf_1162761$t$tx].[gendex] AS [tx]), SEEK:([tx].[generation] >= (1500) AND [tx].[generation] <= (2502)) ORDERED FORWARD)

