Apakah ada manfaat yang masuk akal bagi spool iterator dalam rencana pertama?
Ini tergantung pada apa yang Anda anggap "masuk akal", tetapi jawabannya sesuai dengan model biaya adalah ya. Tentu saja ini benar, karena pengoptimal selalu memilih paket termurah yang ditemukannya.
Pertanyaan sebenarnya adalah mengapa model biaya menganggap paket dengan spul jauh lebih murah daripada tanpa paket. Pertimbangkan taksiran rencana yang dibuat untuk tabel baru (dari skrip Anda) sebelum baris ditambahkan ke delta store:
DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE);
Perkiraan biaya untuk rencana ini adalah 771.734 unit :
Biaya hampir semuanya terkait dengan Penghapusan Indeks Berkelompok, karena penghapusan diharapkan menghasilkan banyak I / O acak. Ini hanya logika umum yang berlaku untuk semua modifikasi data. Sebagai contoh, serangkaian modifikasi yang tidak teratur pada indeks b-tree diasumsikan menghasilkan I / O yang sebagian besar acak, dengan biaya I / O yang tinggi.
Paket pengubah data dapat menampilkan Urut untuk menyajikan baris dalam urutan yang akan mempromosikan akses sekuensial, untuk alasan biaya ini. Dampaknya diperburuk dalam kasus ini karena tabel dipartisi. Faktanya sangat dipartisi; skrip Anda menciptakan 15.000 di antaranya. Pembaruan acak untuk tabel yang sangat dipartisi sangat mahal terutama karena harga untuk beralih partisi (rowsets) mid-stream diberikan biaya tinggi juga.
Faktor utama terakhir yang perlu dipertimbangkan adalah bahwa permintaan pembaruan sederhana di atas (di mana 'pembaruan' berarti operasi perubahan data, termasuk penghapusan) memenuhi syarat untuk optimasi yang disebut "berbagi rowset", di mana rowset internal yang sama digunakan untuk pemindaian dan memperbarui tabel. Rencana pelaksanaan masih menunjukkan dua operator yang terpisah, namun demikian, hanya ada satu rowset yang digunakan.
Saya menyebutkan ini karena dapat menerapkan optimasi ini berarti optimizer mengambil jalur kode yang sama sekali tidak mempertimbangkan manfaat potensial dari penyortiran secara eksplisit untuk mengurangi biaya I / O acak. Di mana tabel adalah b-tree, ini masuk akal, karena strukturnya secara inheren dipesan, sehingga berbagi rowset memberikan semua manfaat potensial secara otomatis.
Konsekuensi penting adalah bahwa logika penetapan biaya untuk operator pembaruan tidak mempertimbangkan manfaat pemesanan ini (mempromosikan I / O berurutan atau optimasi lainnya) di mana objek yang mendasarinya adalah penyimpanan kolom. Ini karena modifikasi penyimpanan kolom tidak dilakukan di tempat; mereka menggunakan toko delta. Oleh karena itu, model biaya mencerminkan perbedaan antara pembaruan shared-rowset pada b-tree versus toko kolom.
Namun demikian, dalam kasus khusus dari kolomstore (sangat!) Yang dipartisi, mungkin masih ada manfaat untuk pemesanan yang diawetkan, dalam melakukan semua pembaruan ke satu partisi sebelum pindah ke yang berikutnya mungkin masih menguntungkan dari sudut pandang I / O. .
Logika biaya standar digunakan kembali untuk penyimpanan kolom di sini, sehingga paket yang mempertahankan pemesanan partisi (meskipun tidak dipesan di setiap partisi) biayanya lebih rendah. Kita dapat melihat ini pada kueri pengujian dengan menggunakan flag jejak 2332 tidak berdokumen untuk memerlukan input yang diurutkan ke operator pembaruan. Ini menyetel DMLRequestSort
properti menjadi true pada pembaruan, dan memaksa optimizer untuk menghasilkan rencana yang menyediakan semua baris untuk satu partisi sebelum pindah ke yang berikutnya:
DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE, QUERYTRACEON 2332);
Perkiraan biaya untuk rencana ini sangat jauh lebih rendah, yaitu 52.5174 unit:
Pengurangan dalam biaya ini semua karena perkiraan biaya I / O yang lebih rendah pada saat pembaruan. Spool yang diperkenalkan tidak melakukan fungsi yang berguna, kecuali ia dapat menjamin output dalam urutan partisi, seperti yang diminta oleh pembaruan dengan DMLRequestSort = true
(pemindaian serial indeks penyimpanan kolom tidak dapat memberikan jaminan ini). Biaya spool itu sendiri dianggap relatif rendah, terutama dibandingkan dengan pengurangan (mungkin tidak realistis) dalam biaya pada pembaruan.
Keputusan tentang apakah memerlukan input yang dipesan untuk operator pembaruan dibuat sangat awal dalam optimasi kueri. Heuristik yang digunakan dalam keputusan ini tidak pernah didokumentasikan, tetapi dapat ditentukan melalui coba-coba. Tampaknya ukuran setiap toko delta adalah masukan untuk keputusan ini. Setelah dibuat, pilihannya permanen untuk kompilasi permintaan. Tidak ada USE PLAN
petunjuk yang akan berhasil: target paket telah memerintahkan input ke pembaruan, atau tidak.
Ada cara lain untuk mendapatkan rencana berbiaya rendah untuk kueri ini tanpa secara artifisial membatasi perkiraan kardinalitas. Perkiraan yang cukup rendah untuk menghindari Spool mungkin akan mengakibatkan DMLRequestSort salah, menghasilkan perkiraan biaya rencana yang sangat tinggi karena I / O acak yang diharapkan. Alternatifnya adalah menggunakan jejak flag 8649 (paket paralel) bersamaan dengan 2332 (DMLRequestSort = true):
DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE, QUERYTRACEON 2332, QUERYTRACEON 8649);
Ini menghasilkan rencana yang menggunakan pemindaian paralel mode per-partisi per-partisi dan pertukaran Pengumpulan (penggabungan) pelestarian pesanan:
Tergantung pada efektivitas run-time pemesanan partisi pada perangkat keras Anda, ini mungkin melakukan yang terbaik dari ketiganya. Yang mengatakan, modifikasi besar bukan ide bagus di kolom toko, jadi ide partisi-switching hampir pasti lebih baik. Jika Anda dapat mengatasi waktu kompilasi yang lama dan pilihan rencana yang aneh sering terlihat dengan objek yang dipartisi - terutama ketika jumlah partisi besar.
Menggabungkan banyak fitur yang relatif baru, terutama di dekat batasnya, adalah cara yang bagus untuk mendapatkan rencana eksekusi yang buruk. Kedalaman dukungan pengoptimal cenderung meningkat dari waktu ke waktu, tetapi menggunakan 15.000 partisi toko kolom kemungkinan akan selalu berarti Anda hidup di masa yang menarik.
OPTION (QUERYRULEOFF EnforceHPandAccCard)
gulungan hilang. Saya menganggap HP mungkin "Halloween Protection". Namun kemudian mencoba menggunakan rencana itu dengan sebuahUSE PLAN
petunjuk gagal (seperti halnya mencoba menggunakan rencana dariOPTIMIZE FOR
solusi juga)