Bagaimana Anda menafsirkan rencana penjelasan kueri?


88

Ketika mencoba untuk memahami bagaimana pernyataan SQL dijalankan, terkadang disarankan untuk melihat rencana penjelasan. Apa proses yang harus dilalui seseorang dalam menafsirkan (memahami) rencana penjelasan? Apa yang seharusnya menonjol seperti, "Oh, ini bekerja dengan sangat baik?" versus "Oh tidak, itu tidak benar."

Jawaban:


81

Saya merinding setiap kali saya melihat komentar bahwa tablescan lengkap itu buruk dan akses indeksnya bagus. Pemindaian tabel lengkap, pemindaian rentang indeks, pemindaian indeks penuh cepat, loop bersarang, gabung gabungan, gabungan hash, dll. Hanyalah mekanisme akses yang harus dipahami oleh analis dan dikombinasikan dengan pengetahuan tentang struktur basis data dan tujuan kueri dalam untuk mencapai kesimpulan yang berarti.

Pemindaian penuh hanyalah cara paling efisien untuk membaca sebagian besar blok segmen data (tabel atau tabel (sub) partisi), dan, meskipun sering kali dapat menunjukkan masalah kinerja, itu hanya dalam konteks apakah itu merupakan mekanisme yang efisien untuk mencapai tujuan kueri. Berbicara sebagai gudang data dan orang BI, bendera peringatan nomor satu saya untuk kinerja adalah metode akses berbasis indeks dan loop bersarang.

Jadi, untuk mekanisme bagaimana membaca rencana penjelasan, dokumentasi Oracle adalah panduan yang baik: http://download.oracle.com/docs/cd/B28359_01/server.111/b28274/ex_plan.htm#PFGRF009

Bacalah juga Performance Tuning Guide dengan baik.

Juga memiliki Google untuk "umpan balik kardinalitas", teknik di mana rencana menjelaskan dapat digunakan untuk membandingkan estimasi kardinalitas pada berbagai tahap dalam kueri dengan kardinalitas aktual yang dialami selama eksekusi. Wolfgang Breitling adalah penulis metode ini, saya yakin.

Jadi, intinya: pahami mekanisme akses. Pahami database. Pahami maksud kueri. Hindari aturan praktis.


5
Aku tahu itu kamu setelah 9 kata pertama. Ini seperti "beri nama lagu itu" ... Saya dapat mengidentifikasi pos Dave A dalam n kata atau kurang ...

Saya akan sedikit berdalih dengan penggunaan "besar" Anda ... terkadang data dapat dikelompokkan dengan sangat buruk di sekitar kolom indeks Anda sehingga FTS akan melakukan pemindaian indeks bahkan untuk 10% baris ...

1
Di 10% - tentu saja. Jika Anda memiliki 200 baris per blok dan Anda mencari 0,5% baris, maka Anda mungkin secara teoritis harus mengakses 100% blok untuk mendapatkan semua nilai, sehingga nilainya menjadi lebih ekstrim dari 10%.
David Aldridge


5

Dua contoh di bawah ini menunjukkan pemindaian LENGKAP dan pemindaian CEPAT menggunakan INDEX.

Yang terbaik adalah berkonsentrasi pada Biaya dan Kardinalitas Anda. Melihat contoh penggunaan indeks mengurangi Biaya menjalankan kueri.

Ini sedikit lebih rumit (dan saya tidak memiliki pegangan 100% di atasnya) tetapi pada dasarnya Biaya adalah fungsi dari biaya CPU dan IO, dan Kardinalitas adalah jumlah baris yang diharapkan Oracle untuk diurai. Mengurangi keduanya adalah hal yang baik.

Jangan lupa bahwa Biaya kueri dapat dipengaruhi oleh kueri Anda dan model pengoptimal Oracle (misalnya: BIAYA, PILIH, dll.) Dan seberapa sering Anda menjalankan statistik.

Contoh 1:

PINDAI http://docs.google.com/a/shanghainetwork.org/File?id=dd8xj6nh_7fj3cr8dx_b

Contoh 2 menggunakan Indeks:

INDEX http://docs.google.com/a/fukuoka-now.com/File?id=dd8xj6nh_9fhsqvxcp_b

Dan seperti yang sudah disarankan, hati-hati terhadap TABLE SCAN. Biasanya Anda dapat menghindari ini.


Uh, Mode aturan tidak memiliki biaya ... jadi saya kira pernyataan Anda benar dalam cara yang paling absolut tetapi saya akan mengatakan bahwa itu pada dasarnya tidak akurat. Jika Anda mengatakan PILIH, Anda bisa mendapatkan RBO atau CBO. CBO adalah satu-satunya yang menghitung biaya.

4

Mencari hal-hal seperti pemindaian berurutan bisa jadi agak berguna, tetapi kenyataannya ada pada angka ... kecuali jika jumlahnya hanya perkiraan! Apa yang biasanya jauh lebih berguna daripada melihat rencana kueri adalah melihat eksekusi sebenarnya . Di Postgres, inilah perbedaan antara MENJELASKAN dan MENJELASKAN ANALISA. JELASKAN ANALISIS sebenarnya mengeksekusi kueri, dan mendapatkan informasi waktu nyata untuk setiap node. Yang memungkinkan Anda melihat apa yang sebenarnya terjadi, bukan apa yang perencana berpikir akan terjadi. Sering kali Anda akan menemukan bahwa pemindaian berurutan bukanlah masalah sama sekali, melainkan sesuatu yang lain dalam kueri.

Kunci lainnya adalah mengidentifikasi langkah mahal yang sebenarnya. Banyak alat grafis akan menggunakan panah dengan ukuran berbeda untuk menunjukkan berapa banyak bagian yang berbeda dari biaya paket. Dalam hal ini, cari saja langkah-langkah yang memiliki panah tipis masuk dan panah tebal keluar. Jika Anda tidak menggunakan GUI, Anda harus mengamati angkanya dan mencari di mana mereka tiba-tiba menjadi jauh lebih besar. Dengan sedikit latihan, menjadi cukup mudah untuk memilih area masalah.


3

Sungguh untuk masalah seperti ini, hal terbaik yang bisa dilakukan adalah ASKTOM . Secara khusus, jawabannya atas pertanyaan itu berisi tautan ke dokumen Oracle online, di mana banyak aturan semacam itu dijelaskan.

Satu hal yang perlu diingat, menjelaskan rencana adalah tebakan terbaik.

Sebaiknya Anda belajar menggunakan sqlplus, dan bereksperimen dengan perintah AUTOTRACE. Dengan beberapa angka pasti, Anda biasanya dapat membuat keputusan yang lebih baik.

Tapi Anda harus ASKTOM. Dia tahu semua tentang itu :)


2

Output dari penjelasan memberi tahu Anda berapa lama setiap langkah telah dilakukan. Hal pertama adalah menemukan langkah-langkah yang memakan waktu lama dan memahami apa artinya. Hal-hal seperti pemindaian sekuensial memberi tahu Anda bahwa Anda memerlukan indeks yang lebih baik - ini sebagian besar adalah masalah penelitian ke dalam basis data dan pengalaman khusus Anda.


2

Satu "Oh tidak, itu tidak benar" sering kali dalam bentuk pemindaian tabel . Pemindaian tabel tidak menggunakan indeks khusus apa pun dan dapat berkontribusi pada pembersihan setiap berguna dalam cache memori. Di postgreSQL, misalnya, Anda akan menemukan tampilan seperti ini.

Seq Scan on my_table  (cost=0.00..15558.92 rows=620092 width=78)

Terkadang pemindaian tabel lebih ideal, katakanlah, menggunakan indeks untuk menanyakan baris. Namun, ini adalah salah satu pola bendera merah yang tampaknya Anda cari.


2
(Penuh) Pemindaian tabel tidak selalu membersihkan cache memori.
a_horse_with_no_name

2

Pada dasarnya, Anda memperhatikan setiap operasi dan melihat apakah operasi tersebut "masuk akal" mengingat pengetahuan Anda tentang bagaimana seharusnya dapat bekerja.

Misalnya, jika Anda menggabungkan dua tabel, A dan B pada masing-masing kolom C dan D (AC = BD), dan rencana Anda menunjukkan pemindaian indeks berkerumun (istilah SQL Server - tidak yakin istilah oracle) pada tabel A, kemudian loop bersarang bergabung dengan serangkaian indeks berkerumun mencari di tabel B, Anda mungkin berpikir ada masalah. Dalam skenario itu, Anda mungkin mengharapkan mesin untuk melakukan sepasang pemindaian indeks (di atas indeks pada kolom yang digabungkan) diikuti dengan gabungan gabungan. Penyelidikan lebih lanjut mungkin mengungkapkan statistik buruk yang membuat pengoptimal memilih pola gabungan tersebut, atau indeks yang sebenarnya tidak ada.


1

lihat persentase waktu yang dihabiskan di setiap sub-bagian dari rencana, dan pertimbangkan apa yang dilakukan mesin. misalnya, jika memindai tabel, pertimbangkan untuk meletakkan indeks pada bidang yang sedang dipindai


1

Saya terutama mencari scan indeks atau tabel. Ini biasanya memberi tahu saya bahwa saya kehilangan indeks pada kolom penting yang ada di pernyataan where atau join.

Dari http://www.sql-server-performance.com/tips/query_execution_plan_analysis_p1.aspx :

Jika Anda melihat salah satu dari hal berikut dalam rencana pelaksanaan, Anda harus mempertimbangkannya sebagai tanda peringatan dan menyelidikinya untuk kemungkinan masalah kinerja. Masing-masing kurang dari ideal dari perspektif kinerja.

* Index or table scans: May indicate a need for better or  additional indexes.
* Bookmark Lookups: Consider changing the current clustered index,
  consider using a covering index, limit
  the number of columns in the SELECT
  statement.
* Filter: Remove any functions in the WHERE clause, don't include wiews
  in your Transact-SQL code, may need
  additional indexes.
* Sort: Does the data really need to be sorted? Can an index be used to
  avoid sorting? Can sorting be done at
  the client more efficiently? 

Tidak selalu mungkin untuk menghindari ini, tetapi semakin Anda dapat menghindarinya, semakin cepat kinerja kueri.


1
Pemindaian tabel tidak semuanya buruk - tergantung pada jumlah catatan yang dikembalikan / diproses dari tabel, pemindaian tabel lengkap bisa lebih cepat daripada pemindaian indeks (jika Anda tetap ingin mengembalikan catatan, Anda akan melakukan pemindaian indeks dan pembacaan lengkap dari tabel - 2 langkah, bukan 1).
ScottCher

-7

Aturan Thumb

(Anda mungkin ingin membaca detailnya juga:

Buruk

Scan Tabel dari Beberapa Tabel Besar

Baik

Menggunakan indeks indeks unik
mencakup semua bidang wajib

Kemenangan Paling Umum

Di sekitar 90% masalah kinerja yang saya lihat, kemenangan termudah adalah memecah kueri dengan banyak (4 atau lebih) tabel menjadi 2 kueri yang lebih kecil dan tabel sementara.


2
Tabel Scan terlalu sering dilihat sebagai hal yang buruk dan pada awalnya apa yang akan difokuskan oleh orang yang tidak berpengalaman. Ini sangat tergantung pada jumlah record yang dikembalikan dari tabel itu, ada batasan saat lebih cepat untuk melakukan scan tabel penuh daripada pencarian indeks.
ScottCher

8
Tidak disukai karena saran yang keterlaluan. 90% masalah kinerja TIDAK diselesaikan dengan tabel temp dan memisahkan kueri. Anda tinggal di dunia apa ?!
TheSoftwareJedi

@ Jedi, saya hidup di dunia di mana sebagian besar ketidaksopanan adalah benar dan database cukup terstruktur dengan baik. Saya akan tertarik untuk membaca jawaban Anda.
AJ.
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.