"Peringatan: Operasi menyebabkan I / O residu" versus pencarian kunci

9

Saya telah melihat peringatan ini dalam paket eksekusi SQL Server 2017:

Peringatan: Operasi menyebabkan sisa IO [sic]. Jumlah aktual baris yang dibaca adalah (3.321.318), tetapi jumlah baris yang dikembalikan adalah 40.

Berikut ini cuplikan dari SQLSentry PlanExplorer:

Masukkan deskripsi gambar di sini

Untuk meningkatkan kode, saya telah menambahkan indeks non-cluster, sehingga SQL Server bisa sampai ke baris yang relevan. Ini berfungsi dengan baik, tetapi biasanya akan ada terlalu banyak kolom (besar) untuk dimasukkan dalam indeks. Ini terlihat seperti ini:

Masukkan deskripsi gambar di sini

Jika saya hanya menambahkan indeks, tanpa menyertakan kolom, akan terlihat seperti ini, jika saya memaksakan penggunaan indeks:

Masukkan deskripsi gambar di sini

Jelas, SQL Server menganggap pencarian kunci jauh lebih mahal daripada sisa I / O. Saya memiliki pengaturan pengujian tanpa banyak data pengujian (belum), tetapi ketika kode masuk ke produksi, perlu bekerja dengan lebih banyak data, jadi saya cukup yakin bahwa semacam indeks NonClustered diperlukan.

Apakah pencarian kunci benar-benar mahal , ketika Anda menjalankan pada SSD, bahwa saya harus membuat indeks penuh lemak (dengan banyak kolom termasuk)?


Rencana eksekusi: https://www.brentozar.com/pastetheplan/?id=SJtiRte2X Ini adalah bagian dari prosedur lama yang tersimpan. Carilah IX_BatchNo_DeviceNo_CreatedUTC.

Henrik Staun Poulsen
sumber
Pertanyaan untuk Anda - Berdasarkan paragraf terakhir Anda, mengapa biaya pencarian lebih murah berdasarkan perangkat keras? (Diasumsikan perangkat keras yang sama dengan indeks non-clustered akan berjalan) Saya tidak jelas tentang itu.
George.Palacios
4
Ini diperkirakan menjadi 76,9% dari biaya rencana itu . Itu tidak berarti mahal. Lihatlah biaya I / O 0,06 dibandingkan dengan rencana awal Anda dengan biaya I / O lebih dari 10. Saya pikir Anda akan lebih baik, tetapi Anda harus menguji dengan rencana aktual terhadap data yang cukup yang benar-benar mensimulasikan seperti apa produksi nantinya ( dan jika kueri berjalan cukup lama bagi kami untuk mengumpulkan data sys.dm_exec_query_profiles, kami akan membebani ulang biayanya dari biaya aktual vs. perkiraan). Berhentilah menggunakan estimasi biaya% karena beberapa indikator biaya mutlak - relatif dan sering keluar untuk makan siang.
Aaron Bertrand
@AaronBertrand; perkiraan biaya pencarian kunci adalah 31.0. Apakah Anda memberi tahu saya bahwa SQL Server tidak mengetahui biaya IO residual?
Henrik Staun Poulsen
Di mana Anda melihat 31.0? Dan maksud Anda 31.0 atau 31.0%?
Aaron Bertrand
1
Tidak, saya mengatakan bahwa biaya yang Anda lihat adalah perkiraan biaya dan, seperti yang dijelaskan Paul di bawah ini, tidak mencerminkan kinerja runtime.
Aaron Bertrand

Jawaban:

16

Model biaya yang digunakan oleh pengoptimal persis seperti itu: model . Ini menghasilkan hasil yang umumnya baik pada berbagai beban kerja, pada berbagai desain database, pada berbagai perangkat keras.

Anda umumnya tidak boleh berasumsi bahwa perkiraan biaya individu akan sangat berkorelasi dengan kinerja runtime pada konfigurasi perangkat keras tertentu. Inti dari penetapan biaya adalah untuk memungkinkan pengoptimal untuk membuat pilihan berpendidikan antara kandidat alternatif fisik untuk operasi logis yang sama.

Ketika Anda benar-benar masuk ke dalam perincian, seorang profesional basis data yang terampil (dengan waktu luang untuk menyetel kueri penting) seringkali dapat melakukan yang lebih baik. Sejauh itu, Anda dapat menganggap pemilihan paket pengoptimal sebagai titik awal yang baik. Dalam kebanyakan kasus, titik awal itu juga akan menjadi titik akhir, karena solusi yang ditemukan cukup baik .

Dalam pengalaman saya (dan pendapat) biaya pengoptimal permintaan SQL Server pencarian lebih tinggi daripada yang saya inginkan. Ini sebagian besar adalah mabuk dari hari-hari ketika I / O fisik acak jauh lebih mahal dibandingkan dengan akses berurutan daripada yang sering terjadi saat ini.

Tetap saja, pencarian bisa menjadi mahal bahkan pada SSD, atau pada akhirnya bahkan ketika membaca secara eksklusif dari memori. Melintasi struktur b-tree tidak gratis. Jelas biaya meningkat saat Anda melakukan lebih banyak.

Kolom yang disertakan sangat bagus untuk beban kerja OLTP yang berat, di mana pertukaran antara penggunaan ruang indeks dan biaya pembaruan versus kinerja saat membaca runtime masuk akal. Ada juga trade-off untuk dipertimbangkan seputar stabilitas rencana . Indeks yang mencakup sepenuhnya menghindari pertanyaan tentang kapan tepatnya model biaya pengoptimal dapat beralih dari satu alternatif ke yang lain.

Hanya Anda yang dapat memutuskan apakah kompromi tersebut layak untuk kasus Anda. Uji kedua alternatif pada sampel data yang representatif, dan buat pilihan yang tepat.

Dalam komentar pertanyaan yang Anda tambahkan:

Apakah Anda memberi tahu saya bahwa SQL Server tidak mengetahui biaya IO residual?

Tidak, pengoptimal mempertimbangkan biaya sisa I / O. Memang, sejauh menyangkut pengoptimal, predikat non-SARGable dievaluasi dalam Filter terpisah. Filter ini didorong ke pencarian atau pemindaian sebagai residu selama penulisan ulang pasca optimasi .

Paul White 9
sumber
Terimakasih banyak atas jawaban Anda. Saya akan mencoba mengikuti saran Anda tentang data uji, sehingga saya bisa mengetahui indeks apa yang benar-benar saya butuhkan. Adalah baik untuk mengetahui bahwa Anda pikir pencarian harus lebih murah pada SSD. Ini pertanda baik untuk vNext.
Henrik Staun Poulsen