Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Cara paling efisien untuk PILIH baris DI MANA ID ADA DI tabel kedua

Ringkasan:

Saya menjalankan setiap kueri 10 kali masing-masing menggunakan kumpulan data pengujian di bawah ini..

  1. Kumpulan hasil subkueri yang sangat besar (100000 baris)
  2. Duplikat baris
  3. 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.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara menjalankan prosedur tersimpan beberapa kali

  2. SQL:Transpose Nyata

  3. T-SQL COALESCE GROUPING SET menjadi satu kolom tanpa duplikat NULL

  4. Tidak dapat menemukan objek karena tidak ada atau Anda tidak memiliki izin. Kesalahan di SQL Server

  5. Cara mendapatkan baris acak dari Tabel SQL Server - Tutorial SQL Server / TSQL Bagian 117