SQL Server, TOP versus ROW_NUMBER

8

Saya belajar tentang rencana Eksekusi dan saya mencoba berbagai pertanyaan dan membandingkan kinerja mereka dan menemukan ini:

SELECT StatisticID
FROM (
    SELECT StatisticID, ROW_NUMBER() OVER (ORDER BY StatisticID) AS rn
    FROM FTCatalog.Statistic
    ) AS T
WHERE T.rn <= 1000
ORDER BY rn

SELECT TOP 1000 StatisticID
FROM FTCatalog.Statistic
ORDER BY StatisticID

Mereka berdua mengembalikan hasil yang sama - namun yang pertama mengeksekusi lebih cepat dan lebih sedikit sumber daya yang lapar (setidaknya SSMS memberitahu saya bahwa) Berikut adalah rencana eksekusi: Rencana eksekusi

Perbandingan dari SQL Query Plan Explorer: masukkan deskripsi gambar di sini Adakah yang bisa memberi saya wawasan tentang apa yang sebenarnya terjadi di balik layar dan mengapa hasilnya berbeda? Jika ada hal lain yang Anda butuhkan - beri tahu saya.

Terima kasih, Evaldas.

Evaldas Buinauskas
sumber
Untuk beberapa alasan SQL Server tidak memiliki penulisan ulang kueri yang baik untuk kueri paging. Perbedaan dalam rencana dan estimasi ini seharusnya tidak ada untuk kasus umum seperti itu.
usr

Jawaban:

11

Saya kira Anda membandingkan perkiraan biaya untuk kueri. Itu hanya perkiraan berdasarkan (antara lain) perkiraan jumlah baris yang dikembalikan oleh permintaan. Bukan jumlah baris yang sebenarnya.

Permintaan pertama Anda memperkirakan bahwa itu akan menghasilkan 30 baris dan permintaan kedua Anda memperkirakan 1000 baris. Dari situlah perbedaan Anda dalam biaya permintaan berasal.

Jika Anda mengubah kueri untuk mengambil hanya 30 baris, Anda akan melihat bahwa baris yang diperkirakan sama untuk kueri dan permintaan pertama sebenarnya biayanya sedikit lebih tinggi, setidaknya bagi saya di SQL Server 2014.

Jangan gunakan taksiran saat membandingkan kinerja kueri. Gunakan hal-hal seperti durasi, jumlah bacaan dan ukuran hibah memori sebagai gantinya.

Mikael Eriksson
sumber
1
Untuk memastikan kinerja aktual, jalankan setiap kueri beberapa kali (GO 10) dengan opsi Sertakan Statistik Klien. Saya menduga Anda akan menemukan waktu eksekusi aktual lebih dekat daripada perkiraan biaya relatif. Tidak ada keajaiban di balik selimut; operator rencana kueri menceritakan kisah nyata.
Dan Guzman
Apakah biaya relatif (persentase ekspresi) sebenarnya berarti sesuatu dalam SSMS? Itu yang paling menggangguku.
Evaldas Buinauskas
@EvaldasBuinauskas Tidak yakin apakah biaya relatif berguna untuk apa pun. Mungkin kadang-kadang tetapi saya tidak berpikir itu bisa bernilai semua kebingungan yang diciptakannya ketika orang mulai menggunakan persentase yang diperkirakan untuk membandingkan kinerja berbagai pertanyaan. Itu akan selalu menjadi estimasi dan estimasi selalu (hampir) salah.
Mikael Eriksson
@EvaldasBuinauskas, biaya-biaya tersebut dikumpulkan selama proses optimasi dan diekspos, tetapi tidak dimaksudkan sebagai indikator atau waktu menjalankan aktual. Biaya hanya tebakan terbaik. Lihat blogs.msdn.com/b/sqlqueryprocessing/archive/2006/10/11/…
Dan Guzman