Petunjuk Optimasi SQL Server 2005/8


13

Saya sedang mencari cara mendidik tim untuk menulis pertanyaan SQL Server yang lebih baik dan bertanya-tanya apa petunjuk terbaik orang untuk meningkatkan kinerja.

Misalnya saya pernah memiliki DBA yang bersikeras bahwa penghitungan (*) akan berkinerja lebih buruk dari penghitungan (1) (Saya tidak tahu apakah dia benar atau apakah masih valid terhadap pengoptimal permintaan terbaru).

Hal sederhana apa yang harus saya katakan kepada tim untuk dicoba dan selalu digunakan atau dihindari? Saya idealnya mencari hal-hal yang (a) mungkin membuat perbedaan yang masuk akal dan (b) lurus ke depan, 1 - 2 baris untuk dinyatakan.

Jawaban:


13

Penyetelan kueri 101

Tidak ada peluru perak ajaib untuk pencarian nada, meskipun saya bisa memberi Anda beberapa petunjuk dan tips. Hal pertama yang harus dilakukan adalah memahami apa yang sebenarnya terjadi di balik layar. Dapatkan buku internal yang bagus seperti buku Panduan Guru ketiga.

Kueri yang berkinerja buruk cenderung memiliki dua rasa dasar: Kueri transaksional yang membutuhkan waktu terlalu lama, dan pekerjaan penggilingan batch (atau laporan) yang terlalu lama. Satu pertanda baik dari kueri dengan sesuatu yang salah dengannya adalah satu item dalam rencana kueri yang menghabiskan 99% waktu.

Kueri transaksional

Pada sebagian besar kesempatan, kueri transaksional yang berkinerja buruk adalah salah satu dari beberapa hal:

  • Indeks yang hilang. Anda dapat melihat ini dalam rencana kueri - pemindaian tabel dari tabel besar pada gabungan yang harus sangat selektif (yaitu mengembalikan beberapa baris).

  • Kueri tidak dapat menggunakan indeks. Jika Anda memiliki kondisi ATAU di mana klausa, bergabung dengan nilai yang dihitung atau beberapa item lain dalam kueri yang tidak mampu-sarg maka Anda mungkin perlu menulis ulang kueri. Secara singkat, sarg adalah predikat permintaan yang dapat menggunakan indeks untuk menghilangkan baris. DAN logis, persamaan dan ketidaksetaraan (>,> =, <, <= dan! =) Semuanya mampu. ATAU secara tradisional tidak mampu. Namun, Anda sering dapat menerjemahkan OR menjadi predikat sarg-mampu dengan membalik arti dari OR ke NOT (foo dan not bar) konstruksi jenis.

  • Predikat tidak efisien. Misalnya, jika Anda memiliki where inreferensi subquery bersarang, lihat apakah itu dapat ditulis ulang sebagai where existsatau sebagai gabungan. Ini dapat menghasilkan rencana permintaan yang lebih efisien dan berikut ini adalah penulisan ulang standar lainnya yang dapat Anda coba juga. Sekali lagi, buku panduan Guru dan yang lainnya tentang masalah ini adalah titik awal yang baik.

Kueri batch

Kueri batch lebih rumit dan memiliki masalah penyetelan yang berbeda. Beberapa tips adalah:

  • Pengindeksan. Ini dapat membuat perbedaan besar karena alasan yang sama dengan pertanyaan transaksional. Seringkali pertanda baik dari indeks yang hilang adalah operasi penggilingan yang panjang (99% dari rencana kueri) yang tampaknya tidak meremukkan mesin.

  • Meja sementara. Anda mungkin menemukan lebih baik untuk memecah kueri menjadi beberapa kueri yang mengisi tabel sementara. Kueri yang lebih besar memberi optimizer lebih banyak ruang untuk dikacaukan, meskipun ini bukan masalah yang biasa. Buat tabel temp dengan select intooperasi ini dicatat minimal (apalagi aktivitas log), yang mengurangi beban I / O.

    Perhatikan bahwa tabel sementara di tempdb adalah struktur data yang sama yang digunakan pengoptimal untuk menyimpan hasil gabungan antara, jadi tidak ada penalti kinerja untuk melakukan ini. Anda juga dapat membuat indeks (termasuk indeks berkerumun dan mencakup) pada tabel temp, yang dapat meningkatkan kinerja kueri membacanya karena alasan yang sama bahwa mereka meningkatkan kueri pada tabel statis.

    Jangan berlebihan tabel temp, karena mereka dapat membuat hal-hal sulit untuk dilacak kembali melalui kueri. Untuk tabel yang lebih kecil dalam prosedur tersimpan, uji untuk melihat apakah variabel tabel membantu. Ini adalah struktur data dalam memori, sehingga dapat menjadi kinerja yang unggul.

  • Indeks berkerumun dan mencakup. Ini dapat meningkatkan kinerja kueri karena memaksa lokalitas referensi pada disk berdasarkan pada beberapa kolom pengelompokan. Indeks berkerumun dapat membuat perbedaan besar untuk kinerja pekerjaan batch.

  • Predikat tidak efisien. Ini dapat menyebabkan masalah dengan sargs dan penilaian sub-optimasi lainnya dengan cara yang sama seperti yang mereka lakukan dengan permintaan transaksional.

  • Pemindaian tabel adalah teman Anda. Bertolak belakang dengan kepercayaan populer, pemindaian meja secara inheren tidak jahat. Umumnya mereka adalah tanda sesuatu yang salah dalam permintaan transaksional, tetapi mereka sering merupakan cara paling efisien untuk melakukan operasi batch besar. Jika Anda melakukan sesuatu dengan lebih dari beberapa persen baris dalam sebuah tabel, pemindaian tabel seringkali merupakan cara paling efisien untuk menutupi tabel.

  • Loop bersarang bergabung. Lihatlah apa yang dilakukan pengoptimal di kedua sisi bergabung. Ini bisa tidak efisien jika Anda (misalnya pemindaian tabel dua tabel besar di kedua sisi loop bersarang bergabung. Pertimbangkan menggunakan indeks berkerumun atau order bydan mencoba mengubah operasi menjadi gabungan bergabung atau mengisyaratkan untuk mempromosikan hash bergabung jika satu sisi adalah cukup kecil untuk melakukan ini.

Mengunci

Mengunci juga dapat menyebabkan masalah kinerja. Jika sistem Anda berkinerja sangat buruk, lihat profiler dan penghitung perfmon yang terkait dengan kunci dan periksa apakah ada pertentangan signifikan. sp_who2memiliki kolom 'BlkBy' di set hasil yang akan menunjukkan jika kueri diblokir dan apa yang memblokirnya. Juga, profil dengan kejadian 'deadlock graph' (jika Anda memiliki pertanyaan deadlocking) dan acara terkait kunci dapat berguna untuk memecahkan masalah kunci.


1
Memberi +1 karena ini adalah beberapa informasi hebat tentang penyetelan kinerja (Saya senang berada di kelas Kalen. Dia tahu apa yang sedang dia bicarakan!). Anda bisa menambahkan beberapa informasi tentang tampilan dinamis.
Wayne

3

Petunjuk terbaik: Gunakan SQL Server 2008 dan jalankan Monitor Aktivitas saat tes Anda berjalan. Perhatikan kueri yang paling lama / paling banyak memiliki I / O, dll. Klik kanan kueri itu untuk melihat kueri dan / atau rencana eksekusi.

Berikutnya: belajar memahami rencana eksekusi.

Berikutnya: Gunakan panduan penyetelan basis data.

Langkah-langkah ini akan membantu Anda menghasilkan "petunjuk terbaik" Anda sendiri.



1

Pertama, pengindeksan. Banyak orang tidak menyadari bahwa kunci asing tidak secara otomatis mendapatkan indeks. Karena mereka digunakan dalam gabungan, mereka hampir selalu harus memiliki indeks.

Periksa dengan cermat semua kursor untuk melihat apakah mereka dapat diganti dengan kode berbasis set sebagai gantinya. Saya telah mengubah kode yang berjalan selama berjam-jam hingga detik dengan melakukan ini.

Hindari subkueri. Jika Anda memilikinya dalam kode, ganti dengan bergabung atau bergabung dengan tabel turunan.

Pastikan klausa tempat Anda diisi ulang.

Belajar membaca rencana eksekusi.

Pastikan kantor memiliki beberapa buku bagus tentang penyetelan kinerja.

Variabel tabel lebih baik daripada tabel temp dalam beberapa kasus dan tabel temp berkinerja lebih baik di orang lain, Jika Anda perlu menggunakannya, coba keduanya dan lihat mana yang lebih baik dalam kasus tertentu.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.