Estimasi vs Perbedaan baris aktual (aktual jauh lebih kecil dari perkiraan) - urutkan

8

Saya menjalankan kueri yang memproses beberapa node dari dokumen XML. Perkiraan biaya subtree saya adalah dalam jutaan dan tampaknya semuanya berasal dari operasi semacam sql server melakukan pada beberapa data yang saya ekstrak dari kolom xml melalui XPath. Operasi Urutkan memiliki perkiraan jumlah baris sekitar 19 juta, sedangkan jumlah baris aktual sekitar 800. Permintaan itu sendiri berjalan cukup baik (1 - 2 detik), tetapi perbedaan membuat saya bertanya-tanya tentang kinerja permintaan dan mengapa ini perbedaannya begitu besar?

Peter Smith
sumber
2
Ini mungkin karena statistik yang ketinggalan zaman, tetapi benar-benar mustahil untuk mengatakan tanpa lebih banyak informasi (termasuk struktur tabel / indeks, kueri, dan rencana eksekusi yang sebenarnya - tidak diperkirakan -).
Aaron Bertrand
1
Dari pengalaman saya, rencana kueri yang melibatkan penghancuran XML selalu memiliki perkiraan biaya yang terlalu tinggi. Seperti, ke titik bahwa jika kueri berkinerja baik dalam hal waktu eksekusi, saya hanya mengabaikan angka perkiraan biaya. Saya tidak tahu mengapa ia melakukan itu, tetapi mungkin ada hubungannya dengan tidak tahu berapa banyak XML akan digunakan sebagai input. Namun, jika tujuan Anda adalah meningkatkan kinerja kueri, satu cara yang saya temukan untuk melakukannya adalah dengan menggunakan koleksi skema XML, seperti yang saya blog di sini .
Jon Seigel

Jawaban:

9

Tidak ada statistik yang dihasilkan pada kolom XML. Taksiran ditebak berdasarkan ekspresi yang digunakan saat menanyakan XML.

Menggunakan tabel ini:

create table T(XMLCol xml not null)
insert into T values('<root><item value = "1" /></root>')

Dan permintaan XML ini agak sederhana:

select X.N.value('@value', 'int')
from T
  cross apply T.XMLCol.nodes('root/item') as X(N)

Akan memberi Anda satu baris yang dikembalikan tetapi perkiraan baris yang dikembalikan adalah 200. Itu akan menjadi 200 terlepas dari apa XML atau berapa banyak XML yang Anda masukkan ke dalam kolom XML untuk satu baris itu.

Ini adalah paket kueri dengan perkiraan jumlah baris ditampilkan.

masukkan deskripsi gambar di sini

Cara untuk meningkatkan, atau setidaknya mengubah, perkiraan adalah memberikan pengoptimal permintaan informasi lebih lanjut tentang XML. Dalam hal ini, karena saya tahu itu rootbenar - benar merupakan simpul root dalam XML, saya dapat menulis ulang kueri seperti ini.

select X2.N.value('@value', 'int')
from T
  cross apply T.XMLCol.nodes('root[1]') as X1(N)
  cross apply X1.N.nodes('item') X2(N)

Itu akan memberi saya perkiraan 5 baris yang dikembalikan.

masukkan deskripsi gambar di sini

Penulisan ulang kueri mungkin tidak akan mempercepat penghancuran XML tetapi jika perkiraan lebih baik, kemungkinan pengoptimal kueri dapat membuat keputusan yang lebih cerdas untuk sisa kueri.

Saya belum menemukan dokumentasi tentang apa aturannya untuk perkiraan selain presentasi oleh Michael Rys di mana ia berkata:

Perkiraan kardinalitas dasar selalu 10'000 baris!
Beberapa penyesuaian berdasarkan filter jalur yang didorong

Mikael Eriksson
sumber