HAPUS sederhana, tetapi rencana eksekusi rumit

9

Ketika saya menjalankan penghapusan ini:

DELETE FROM ETLHeaders WHERE ETLHeaderID < 32465870

... menghapus 39.157 baris. Itu harus sederhana karena menghapus pada ETLHeaderID yang merupakan indeks dan kunci utama berkerumun. Tetapi (sesuai dengan rencana eksekusi) tampaknya mencapai 361.190 baris dan menggunakan indeks lainnya. Tabel memang memiliki bidang dengan tipe data XML (dalam kasus yang mempengaruhi HAPUS ini).

Adakah ide mengapa dan bagaimana saya bisa mempercepat HAPUS ini?

Rencana Eksekusi di sini: http://sharetext.org/qwDY Skema tabel di sini: http://sharetext.org/Vl9j

Terima kasih

Craig HB
sumber

Jawaban:

10

Level teratas dari rencana berkaitan dengan menghilangkan baris dari tabel dasar (indeks berkerumun), dan mempertahankan empat indeks yang tidak tercakup. Dua dari indeks ini dipertahankan baris demi baris pada saat yang sama penghapusan indeks berkerumun diproses. Ini adalah "+2 indeks non-clustered" yang disorot dengan warna hijau di bawah ini.

Untuk dua indeks nonclustered lainnya, pengoptimal telah memutuskan yang terbaik untuk menyimpan kunci indeks ini ke meja kerja tempdb (Eager Spool), kemudian memutar spool dua kali, mengurutkan berdasarkan kunci indeks untuk mempromosikan pola akses berurutan.

Pemeliharaan indeks reguler

Urutan akhir operasi berkaitan dengan mempertahankan indeks primer dan sekunder xml, yang tidak termasuk dalam skrip DDL Anda:

Pemeliharaan indeks XML

Tidak banyak yang bisa dilakukan mengenai hal ini. Indeks dan indeks yang tidak tercakup xmlharus tetap disinkronkan dengan data di tabel dasar. Biaya mempertahankan indeks tersebut adalah bagian dari trade-off yang Anda lakukan saat membuat indeks tambahan di atas meja.

Yang mengatakan, xmlindeks sangat bermasalah. Sangat sulit bagi pengoptimal untuk secara akurat menilai berapa banyak baris yang memenuhi syarat dalam situasi ini. Bahkan, ini terlalu berlebihan untuk xmlindeks, menghasilkan hampir 12GB memori yang diberikan untuk permintaan ini (meskipun hanya 28MB digunakan saat runtime):

Taksiran jumlah baris

Anda dapat mempertimbangkan melakukan penghapusan dalam batch yang lebih kecil, dengan harapan dapat mengurangi dampak dari pemberian memori yang berlebihan.

Anda juga bisa menguji kinerja rencana tanpa menggunakan jenis OPTION (QUERYTRACEON 8795). Ini adalah tanda jejak yang tidak berdokumen sehingga Anda hanya boleh mencobanya pada pengembangan atau sistem pengujian, tidak pernah dalam produksi. Jika paket yang dihasilkan jauh lebih cepat, Anda bisa menangkap paket XML dan menggunakannya untuk membuat Panduan Paket untuk kueri produksi.

Paul White 9
sumber
3

Anda berada di jalur yang benar - indeks XML adalah masalahnya. Jelas, ada indeks XML primer dan sekunder.

Saat melakukan DELETE terhadap tabel dasar (ETLHeaders), data harus dihapus dari setiap indeks tabel ini juga. Overhead ini bisa signifikan, terutama untuk indeks XML.

Indeks yang menyebabkan durasi panjang adalah indeks XML sekunder [XML_IX_ETLHeaders_Property]. 39.157 baris dalam "tabel relasional" Anda merujuk ke 361.190 baris dalam indeks XML primer [XML_IX_ETLHeaders]. Dan baris-baris 361k itu perlu disortir agar dapat digunakan untuk menghapus indeks sekunder. Dan operasi semacam ini menyebabkan durasi permintaan yang panjang. (Sebagai catatan, statistik indeks dari kedua indeks xml tampaknya jauh: ukuran data aktual dari 361k baris indeks xml primer adalah 160MB sedangkan perkiraan ukuran data hampir 4TB (ya, 4 TerraByte !!)) .

Satu-satunya opsi yang saya lihat untuk mempercepat kueri ini adalah untuk menghilangkan indeks XML sekunder. Bergantung pada data, ini mungkin merupakan opsi yang lebih baik untuk merobek data XML ke dalam tabel relasional.

Lmu92
sumber