Saya memiliki kelas pertanyaan yang menguji keberadaan satu dari dua hal. Itu adalah bentuk
SELECT CASE
WHEN EXISTS (SELECT 1 FROM ...)
OR EXISTS (SELECT 1 FROM ...)
THEN 1 ELSE 0 END;
Pernyataan aktual dihasilkan dalam C dan dieksekusi sebagai permintaan ad-hoc melalui koneksi ODBC.
Baru-baru ini terungkap bahwa SELECT kedua mungkin akan lebih cepat daripada SELECT pertama dalam banyak kasus dan bahwa mengganti urutan kedua klausa EXISTS menyebabkan percepatan yang drastis dalam setidaknya satu kasus uji kasar yang baru saja kita buat.
Hal yang jelas untuk dilakukan adalah langsung beralih dua klausa, tapi saya ingin melihat apakah seseorang yang lebih akrab dengan SQL Server akan peduli untuk mempertimbangkan ini. Rasanya seperti saya mengandalkan kebetulan dan "detail implementasi".
(Sepertinya SQL Server lebih pintar, itu akan mengeksekusi kedua klausa EXISTS secara paralel dan membiarkan salah satu yang pertama menyelesaikan hubungan pendek yang lain.)
Apakah ada cara yang lebih baik untuk mendapatkan SQL Server untuk secara konsisten meningkatkan waktu berjalan dari permintaan seperti itu?
Memperbarui
Terima kasih atas waktu dan minat Anda pada pertanyaan saya. Saya tidak mengharapkan pertanyaan tentang rencana kueri yang sebenarnya, tetapi saya bersedia membagikannya.
Ini untuk komponen perangkat lunak yang mendukung SQL Server 2008R2 dan lebih tinggi. Bentuk data bisa sangat berbeda tergantung pada konfigurasi dan penggunaan. Rekan kerja saya berpikir untuk melakukan perubahan pada kueri ini karena (dalam contoh) dbf_1162761$z$rv$1257927703tabel akan selalu memiliki lebih besar atau sama dengan jumlah baris di dalamnya daripada dbf_1162761$z$dd$1257927703tabel - kadang-kadang secara signifikan lebih banyak (urutan besarnya).
Ini kasus kasar yang saya sebutkan. Permintaan pertama adalah yang lambat dan memakan waktu sekitar 20 detik. Kueri kedua selesai dalam sekejap.
Untuk apa nilainya, bit "MENGOPTIMALKAN UNTUK TIDAK DIKETAHUI" juga ditambahkan baru-baru ini karena parameter sniffing merusak kasus tertentu.
Permintaan asli:
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)
Rencana asli:
|--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)
Memperbaiki kueri:
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)
Rencana tetap:
|--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)

