Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Menetapkan dan Mengidentifikasi Sasaran Baris dalam Rencana Eksekusi

Pengantar

Dokumentasi produk SQL Server sedikit ringan tentang topik tujuan baris . Referensi resmi utama ada di:

  • Petunjuk (Transact-SQL) – Kueri (FAST dan DISABLE_OPTIMIZER_ROWGOAL petunjuk)
  • DBCC TRACEON – Bendera Pelacakan (Transact-SQL) (tanda pelacakan 4138)
  • Kueri mungkin membutuhkan waktu lama untuk dijalankan jika pengoptimal kueri menggunakan operator Top (KB 2667211)

Ketika orang meminta lebih banyak informasi daripada yang terkandung di sana, saya biasanya merujuk mereka satu atau lebih dari yang berikut:

  • Aksi Baris Sasaran oleh Tim Pengoptimalan Kueri SQL Server
  • Target Baris ditinjau kembali – Panduan petunjuk CEPAT juga oleh Tim Pengoptimalan Kueri SQL Server
  • Gol-Gol Beruntun Hilang dari Bart Duncan
  • Di Dalam Pengoptimal:Tujuan Baris Mendalam oleh saya
  • Tips tuning SSIS yang dirindukan semua orang oleh Rob Farley

Untuk meringkas secara singkat:Fitur tujuan baris memungkinkan pengoptimal untuk menghasilkan rencana eksekusi (atau bagian dari rencana eksekusi) dengan tujuan mengembalikan sejumlah baris dengan cepat. Ini berbeda dengan perilaku normal (tanpa tujuan baris), yang bertujuan untuk menemukan rencana yang dioptimalkan untuk rangkaian hasil potensial yang lengkap.

Strategi sasaran baris umumnya berarti mendukung operasi navigasi non-pemblokiran (misalnya, loop bersarang bergabung, pencarian indeks, dan pencarian) daripada pemblokiran, operasi berbasis set seperti penyortiran dan hashing. Ini dapat berguna setiap kali klien dapat mengambil manfaat dari start-up cepat dan aliran baris yang stabil (mungkin dengan waktu eksekusi keseluruhan yang lebih lama – lihat posting Rob Farley di atas). Ada juga penggunaan yang lebih jelas dan tradisional, mis. dalam menyajikan hasil halaman pada satu waktu.

Secara alami, ada unsur risiko yang terlibat dengan rencana tujuan baris. Jika semuanya berjalan secara luas seperti yang diharapkan pengoptimal (mengingat informasi yang tersedia, dan asumsi pemodelan yang dibuat), rencana eksekusi akan mulai mengalirkan jumlah baris yang diminta lebih cepat dan efisien daripada yang terjadi tanpa tujuan baris.

Sayangnya, ketika strategi tujuan baris salah, itu bisa menjadi bencana kinerja (lihat posting Bart Duncan). Ini dapat terjadi, misalnya, ketika pengoptimal memiliki informasi yang tidak lengkap, menemukan distribusi data yang tidak menguntungkan, atau membuat asumsi yang tidak aman. Bagaimanapun, penyebab kinerja yang buruk hampir selalu karena lebih banyak baris yang perlu diproses pada waktu eksekusi daripada yang diharapkan pengoptimal.

Sangat berguna untuk mengidentifikasi area rencana eksekusi yang dipengaruhi oleh tujuan baris, karena membantu kita memahami mengapa pengoptimal membuat pilihan itu. Ini sangat penting ketika logika tujuan baris menghasilkan hasil yang merugikan. Tanpa memahami peran yang dimainkan oleh sasaran baris, mungkin terlihat seolah-olah pengoptimal meremehkan jumlah baris, membuat orang mencari di tempat yang salah (mis. statistik) untuk mencari akar masalah.

Menetapkan Sasaran Baris

Jauh lebih mudah untuk mencari efek sasaran baris jika seseorang mengetahui hal-hal macam apa yang mungkin menyebabkan sasaran baris ditetapkan di tempat pertama. Dokumentasi resmi sering berbicara tentang sasaran baris yang dikaitkan dengan kata kunci TOP , FAST , IN , dan EXISTS . Hal ini dapat membuat pembaca memiliki pemahaman yang tidak lengkap atau menyesatkan, jadi ada baiknya meluangkan waktu sejenak untuk mengklarifikasi beberapa aspek.

Saya ingin menekankan di awal bahwa menggunakan kata kunci T-SQL tertentu dalam kueri tidak menjamin bahwa sasaran baris akan ditetapkan . Dokumentasi resmi menyebutkan kata kunci tertentu untuk membantu orang mengidentifikasi skenario umum di mana sasaran baris mungkin diperkenalkan, tanpa terlalu banyak membahas teknis.

Hal umum kedua yang perlu diingat adalah bahwa sasaran baris hanya ditetapkan bila sasaran kurang dari perkiraan biasa . Lagi pula, tidak ada gunanya menghasilkan fragmen rencana yang dioptimalkan untuk 100 baris jika semuanya hanya diharapkan menghasilkan 50 baris. Agar lebih jelas, poin ini selalu berlaku untuk semua cara yang dapat dilakukan untuk menetapkan sasaran baris. Jika Anda mengharapkan sasaran baris, tetapi tidak melihatnya, ini kemungkinan penyebabnya.

Terakhir, untuk pembukaan, perhatikan bahwa sasaran baris adalah hal pengoptimalan berbasis biaya; sasaran baris memengaruhi pilihan pengoptimal, jadi jika tidak ada pilihan yang dibuat (yaitu rencana sepele) tidak ada efek sasaran baris.

Sekarang mari kita lihat hal-hal yang dapat menetapkan tujuan baris:

CEPAT dan TOP

Menggunakan FAST petunjuk kueri adalah cara yang andal untuk menetapkan sasaran baris di root dari rencana eksekusi (tunduk pada pengecualian umum yang disebutkan di atas). A SET ROWCOUNT n pernyataan juga menetapkan sasaran baris tingkat atas yang serupa (ketika n tentu saja bukan nol) untuk pernyataan yang berlaku.

Menulis TOP klausa dalam kueri juga sangat sering menghasilkan tujuan baris. Selama rencana eksekusi yang telah selesai menampilkan operator Top fisik, kemungkinan setidaknya sebagian dari rencana di bawah operator Top dipengaruhi oleh sasaran baris (sekali lagi, syarat dan ketentuan umum berlaku).

Perhatikan bahwa Operator teratas diperkenalkan oleh pengoptimal kueri (tanpa TOP yang ditentukan oleh kueri klausa) juga dapat menetapkan tujuan baris. Ini penting, karena ada berbagai cara yang bisa terjadi, misalnya saat memfilter pada nomor baris sederhana, seperti yang ditunjukkan pada kueri AdventureWorks berikut:

SELECT
    THN.RowNum,
    THN.TransactionID 
FROM 
(
    SELECT 
        TH.TransactionID, 
        RowNum = 
            ROW_NUMBER() OVER (
                ORDER BY TH.TransactionID ASC)
    FROM Production.TransactionHistory AS TH
    WHERE
        TH.ProductID = 400
) AS THN
WHERE
    THN.RowNum >= 10
    AND THN.RowNum < 20
ORDER BY
    THN.RowNum ASC;

Rencana eksekusi untuk kueri tersebut mencakup operator Top yang ditambahkan oleh pengoptimal (untuk membatasi jumlah baris yang diproses menjadi 20):