Saya bergabung dengan tabel kecil (1.000 baris) terhadap tabel besar (8M baris) di SQL Server 2008. Gabung menggunakan indeks penutup nonclustered pada tabel besar, dan bergabung dapat menghasilkan tiga kemungkinan rencana kueri. Saya mencoba mencari tahu rencana mana yang lebih baik, tetapi saya juga ingin menggeneralisasi pengetahuan ini sehingga lain kali saya bisa lebih tahu heuristik apa yang akan digunakan ketika melihat statistik SQL I / O.
Plan # 1 adalah loop bergabung dan memancarkan statistik untuk tabel besar seperti ini:
Scan count 2582, logical reads 35686, physical reads 1041, read-ahead reads 23052
Plan # 2 adalah gabungan gabung dan memancarkan statistik seperti ini:
Scan count 1, logical reads 59034, physical reads 49, read-ahead reads 59004
Plan # 3 adalah hash join dan memancarkan statistik seperti ini:
Scan count 3, logical reads 59011, physical reads 5, read-ahead reads 59010
Indeks penutup diperintahkan oleh (ID, Date)
. Kueri mengembalikan data sekitar 50% dari ID dan, untuk setiap ID, mengembalikan potongan yang berdekatan dari data 3 bulan terakhir, yang biasanya sekitar 1/4 atau baris untuk setiap ID. Kueri mengembalikan sekitar 1/8 dari total baris dalam indeks. Dengan kata lain, kueri jarang tetapi secara konsisten demikian.
Asumsi saya adalah bahwa rencana # 1 mengerikan untuk beban kerja ini, karena memindahkan kepala disk sekitar 2.500 kali (atau bahkan 1.041 kali) jauh lebih mahal daripada pemindaian disk berurutan. Saya juga berasumsi bahwa # 3 dan # 2 memiliki pola I / O yang mirip, berurutan (dan karena itu lebih efisien).
Tetapi apakah ada kasus di mana rencana # 1 benar-benar terbaik, di mana "terbaik" berarti lebih sedikit dampak pada subsistem I / O dan lebih sedikit dampak pada kueri lain yang berjalan secara bersamaan?
Atau apakah itu benar-benar tergantung pada banyak variabel seperti jenis subsistem disk yang saya miliki, indeks fragmentasi, dll. Jika "itu tergantung" apakah ada aturan praktis untuk mendekati masalah?