PILIHAN FORCE OPSI meningkatkan kinerja sampai baris dihapus

9

Saya punya query SQL Server 2008 yang agak rumit (sekitar 200 baris SQL yang cukup padat) yang tidak berfungsi seperti yang saya butuhkan. Seiring waktu, kinerja turun dari sekitar 0,5 detik menjadi sekitar 2 detik.

Melihat rencana pelaksanaannya, cukup jelas bahwa dengan menyusun kembali sambungan, kinerja dapat ditingkatkan. Ya, dan itu ... turun menjadi sekitar, 3 detik. Sekarang kueri memiliki petunjuk "OPSI FORCE ORDER" , dan hidup itu baik.

Datanglah saya hari ini, membersihkan database. Saya mengarsipkan sekitar 20% dari baris, tidak mengambil tindakan dalam database yang relevan kecuali menghapus baris ... rencana eksekusi akan BENAR-BENAR disemprot . Ini sepenuhnya salah menilai berapa banyak baris yang akan dikembalikan oleh sub-sub-sub, dan (misalnya) menggantikan:

<Hash>

dengan

<NestedLoops Optimized='false' WithUnorderedPrefetch='true'>

Sekarang waktu kueri melonjak dari sekitar 0,3 detik menjadi sekitar 18 detik. (!) Hanya karena saya menghapus baris. Jika saya menghapus petunjuk permintaan saya kembali ke waktu permintaan 2s. Lebih baik, tapi lebih buruk.

Saya telah mereproduksi masalah setelah memulihkan database ke beberapa lokasi dan server. Cukup menghapus sekitar 20% baris dari setiap tabel selalu menyebabkan masalah ini.

  1. Apakah ini normal untuk pesanan gabungan paksa untuk membuat perkiraan kueri menjadi benar-benar tidak akurat (dan karenanya waktu kueri tidak dapat diprediksi)?
  2. Haruskah saya berharap bahwa saya harus menerima kinerja kueri yang kurang optimal, atau menontonnya seperti elang dan sering mengedit petunjuk kueri secara manual? Atau mungkin mengisyaratkan setiap bergabung juga? 3s ke 2s adalah hit besar untuk diambil.
  3. Apakah jelas mengapa pengoptimal meledak setelah menghapus baris? Misalnya, "ya, diperlukan pemindaian sampel, dan karena saya mengarsipkan sebagian besar baris sebelumnya dalam riwayat data sampel menghasilkan hasil yang jarang, sehingga meremehkan kebutuhan untuk operasi hash yang diurutkan"?

Jika Anda ingin melihat rencana eksekusi, harap sarankan lokasi yang dapat saya posting. Kalau tidak, saya sudah mencicipi sedikit yang paling menakjubkan. Inilah perkiraan salah yang mendasar, angka dalam paren adalah baris (perkiraan: aktual).

                             /  Clustered Index Scan (908:7229)
Nested Loops (Inner Join) --<
                             \  NonClustered Index Seek (1:7229)

Perhatikan bahwa loop dalam diharapkan untuk memindai 908 baris, tetapi sebaliknya memindai 52.258.441. Jika sudah akurat, cabang ini akan berlari sekitar 2ms, bukan 12detik. Sebelum menghapus baris, estimasi gabungan dalam ini hanya dimatikan oleh faktor total 2, dan dilakukan sebagai pencocokan hash pada dua indeks berkerumun.

shannon
sumber

Jawaban:

6

Apakah ini normal untuk pesanan gabungan paksa untuk membuat perkiraan kueri menjadi benar-benar tidak akurat (dan karenanya waktu kueri tidak dapat diprediksi)?

Penggunaan FORCE ORDER tidak membuat perkiraan tidak akurat, penghapusan baris dilakukan. Memaksa pembaruan statistik di atas meja dapat meningkatkan akurasi estimasi.

Haruskah saya berharap bahwa saya harus menerima kinerja kueri yang kurang optimal, atau menontonnya seperti elang dan sering mengedit petunjuk kueri secara manual? Atau mungkin mengisyaratkan setiap bergabung juga? 3s ke 2s adalah hit besar untuk diambil.

Lebih disukai untuk memastikan pengoptimal diberikan informasi yang dibutuhkan untuk menghasilkan rencana terbaik, tanpa menggunakan petunjuk FORCE ORDER. Dengan melakukan itu, ia harus mengatasi dengan lebih baik perubahan pada distribusi data yang mendasarinya tanpa memerlukan intervensi manual. Yang mengatakan, jika sifat data sedemikian sehingga kardinalitas dapat bervariasi secara signifikan dari jam ke jam atau hari ke jam, pertimbangkan untuk menggunakan panduan rencana untuk memastikan rencana tetap.

Apakah jelas mengapa pengoptimal meledak setelah menghapus baris? Misalnya, "ya, diperlukan pemindaian sampel, dan karena saya mengarsipkan sebagian besar baris sebelumnya dalam riwayat data sampel menghasilkan hasil yang jarang, sehingga meremehkan kebutuhan untuk operasi hash yang diurutkan"?

Anda tidak menyebutkan jumlah baris dalam tabel masalah tetapi kemungkinan penghapusannya adalah:

  • tidak menghapus cukup baris untuk memicu pembaruan statistik. Ini harus terjadi ketika 20% dari baris telah dimodifikasi tetapi ada opsi untuk menggunakan jejak bendera 2371 untuk mengaktifkan ambang batas dinamis.
  • memang memicu pembaruan statistik tetapi sampel yang dikumpulkan tidak representatif. Perbaiki ini dengan menjalankan pembaruan manual DENGAN FULLSCAN .

Anda juga bisa mengalami masalah mengendus parameter kuno yang baik , yang ada banyak pilihan untuk bekerja. DENGAN RECOMPILE mungkin merupakan opsi mahal untuk menentukan dengan kueri sebesar ini, tetapi perlu diselidiki pada tingkat prosedur dan pernyataan.

Mark Storey-Smith
sumber
Sekedar klarifikasi, mungkin semantik: "Penggunaan FORCE ORDER tidak membuat perkiraan tidak akurat, penghapusan baris dilakukan." Jadi Anda pikir ini hanya kesempatan acak bahwa menghapus "FORCE ORDER" sangat meningkatkan kueri? Petunjuk itu tidak menyudutkan pengoptimal agar mengandalkan statistik yang lebih ditekankan, atau tidak ditemukan dalam uji coba aplikasi karena statistik yang kurang andal ini jarang penting?
shannon
Saya kira begitu ya, karena optimisers lebih memilih pilihan rencana untuk mengatasi statistik yang tidak akurat tetapi rencana yang dihasilkan dari perintah gabungan dipaksa tidak. Saya tidak mengetahui FORCE ORDER yang menyebabkan perubahan pada evaluasi statistik, orang lain akan berpura-pura jika mereka mengetahui sesuatu yang bertentangan. Juga perlu mempertimbangkan apakah nilai yang Anda pilih untuk MENGOPTIMALKAN cocok. Bisa jadi statistik benar-benar baik-baik saja tetapi Anda memaksakan rencana berdasarkan nilai yang tidak representatif.
Mark Storey-Smith
Baik. Saya memiliki masalah kinerja yang sama melewati parameter persis seperti saya telah mengoptimalkannya. Terima kasih lagi.
shannon