pembacaan logis vs. jumlah pemindaian

8

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?

Justin Grant
sumber
Pembacaan logis langsung dari kumpulan buffer, pembacaan fisik berasal dari disk sehingga masuk akal jika Anda ingin meminimalkan jumlah pembacaan fisik
Bisakah Anda memposting tiga paket permintaan sebagai gambar?
usr

Jawaban:

10

Ini adalah kesepakatan yang mematikan: pada bulan Januari harganya $ 12rb untuk membeli 864 * GB * RAM . Anda bisa mendapatkan banyak keuntungan dengan hanya meningkatkan RAM server Anda hingga Anda tidak akan pernah membaca secara fisik (setelah pemanasan, tentu saja).

Selain itu, sangat sulit untuk memberikan pendapat hitam atau putih tentang salah satu poin data yang Anda sajikan. Tentu rencana # 1 memiliki sebagian besar pembacaan fisik, tetapi apakah Anda yakin semua tes dilakukan pada cache yang sama-sama menghangat? Mungkinkah # 1 memanaskan cache untuk # 2, apa metodologi pengujian Anda untuk memastikan semua kasus dipertimbangkan di permukaan tanah? Meski begitu, jika Anda mengeluarkan $ 500 dan menggandakan RAM, apakah itu penting lagi? # 1 memang memiliki bacaan paling logis ...

Tapi kemudian # 2 mungkin mendapat manfaat dari DOP tinggi (bahwa satu pemindaian bisa paralel). Apakah waktu jam dinding # 2 lebih baik daripada # 1 setelah Anda menambahkan RAM yang cukup?

Berapa banyak dari rencana ini berjalan secara paralel? Apakah ada puluhan permintaan yang secara bersamaan meminta hibah memori yang signifikan untuk hash # 3 dan dengan demikian menciptakan pertikaian untuk RESOURCE_SEMAPHORE? Apakah # 2 melakukan pengurutan dan juga meminta hibah memori? Akankah # 1 bekerja lebih baik karena tidak memerlukan hibah (setidaknya dari info yang diposting ...)?

Benar-benar relatif dan pertanyaan yang Anda ajukan lebih seperti menemukan satu solusi untuk sistem persamaan yang kompleks ... mungkin ada lebih dari satu solusi.

Satu hal yang pasti: 8M baris harus sesuai dengan RAM dengan banyak ruang cadangan. Bacaan fisik itu meminta beberapa bank memori.

Remus Rusanu
sumber
1

Untuk permintaan yang tampaknya sangat sederhana ini, pengoptimal akan secara konsisten menghasilkan rencana terbaik sesuai dengan model biayanya. Model biaya cukup akurat. Jadi rekomendasi saya adalah meninggalkan pilihan ke SQL Server.

Rekomendasi kedua: Ukur durasi kueri untuk ketiga varian dengan cache panas. Kemudian putuskan. (Jangan memutuskan berdasarkan bacaan dan pemindaian dan semacamnya. Yang penting bagi Anda adalah durasi.)

Secara umum, untuk memilih tipe join terbaik (atau indeks) membutuhkan pemahaman tentang bagaimana algoritma join bekerja. Terlalu banyak informasi untuk dikirim di sini.

usr
sumber