Ringkasan:
Saya menjalankan setiap kueri 10 kali masing-masing menggunakan kumpulan data pengujian di bawah ini..
- Kumpulan hasil subkueri yang sangat besar (100000 baris)
- Duplikat baris
- Baris kosong
Untuk semua skenario di atas, keduanya IN
dan EXISTS
dilakukan dengan cara yang sama.
Beberapa info tentang Database Kinerja V3 digunakan untuk pengujian.20000 pelanggan memiliki 1000000 pesanan, sehingga setiap pelanggan diduplikasi secara acak (dalam kisaran 10 hingga 100) di tabel pesanan.
Biaya eksekusi,Waktu:
Di bawah ini adalah screenshot dari kedua query yang sedang berjalan. Amati setiap biaya relatif kueri.
Biaya Memori:
Memori grant untuk kedua query juga sama.. Saya paksakan MDOP 1 agar tidak tumpah ke TEMPDB..
Waktu CPU ,Dibaca:
Untuk Yang Ada:
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Customers'. Scan count 1, logical reads 109, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Orders'. Scan count 1, logical reads 3855, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 469 ms, elapsed time = 595 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
Untuk DI:
(20000 row(s) affected)
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Customers'. Scan count 1, logical reads 109, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Orders'. Scan count 1, logical reads 3855, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 547 ms, elapsed time = 669 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
Dalam setiap kasus, pengoptimal cukup pintar untuk mengatur ulang kueri.
Saya cenderung menggunakan EXISTS
hanya meskipun (pendapat saya). Satu kasus penggunaan untuk menggunakan EXISTS
adalah saat Anda tidak ingin mengembalikan kumpulan hasil tabel kedua.
Pembaruan sesuai kueri dari Martin Smith:
Saya menjalankan kueri di bawah ini untuk menemukan cara paling efektif untuk mendapatkan baris dari tabel pertama yang referensinya ada di tabel kedua.
SELECT DISTINCT c.*
FROM Customers c
JOIN Orders o ON o.custid = c.custid
SELECT c.*
FROM Customers c
INNER JOIN (SELECT DISTINCT custid FROM Orders) AS o ON o.custid = c.custid
SELECT *
FROM Customers C
WHERE EXISTS(SELECT 1 FROM Orders o WHERE o.custid = c.custid)
SELECT *
FROM Customers c
WHERE custid IN (SELECT custid FROM Orders)
Semua kueri di atas memiliki biaya yang sama dengan pengecualian INNER JOIN
ke-2 , Rencanakan hal yang sama untuk yang lainnya.
Hibah Memori:
Kueri ini
SELECT DISTINCT c.*
FROM Customers c
JOIN Orders o ON o.custid = c.custid
diperlukan pemberian memori
Kueri ini
SELECT c.*
FROM Customers c
INNER JOIN (SELECT DISTINCT custid FROM Orders) AS o ON o.custid = c.custid
diperlukan pemberian memori sebesar ..
Waktu CPU, Dibaca:
Untuk Pertanyaan :
SELECT DISTINCT c.*
FROM Customers c
JOIN Orders o ON o.custid = c.custid
(20000 row(s) affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Workfile'. Scan count 48, logical reads 1344, physical reads 96, read-ahead reads 1248, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Orders'. Scan count 5, logical reads 3929, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Customers'. Scan count 5, logical reads 322, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 1453 ms, elapsed time = 781 ms.
Untuk Kueri:
SELECT c.*
FROM Customers c
INNER JOIN (SELECT DISTINCT custid FROM Orders) AS o ON o.custid = c.custid
(20000 row(s) affected)
Table 'Customers'. Scan count 5, logical reads 322, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Orders'. Scan count 5, logical reads 3929, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 1499 ms, elapsed time = 403 ms.