Ada indeks berkerumun di Client
bidang tabel LastName
.
Ketika saya cukup membuang semua catatan dari tabel, mereka muncul dalam urutan abjad kecuali (nolock)
petunjuk digunakan seperti dalam kueri yang dimaksud. Petunjuk itu mengubah urutan catatan. Haruskah itu? Saya yakin tidak ada sesi lain yang memiliki transaksi terbuka dengan perubahan pada tabel tersebut (setidaknya sp_who2
tidak menunjukkan kepada saya apa pun).
Bagaimana perbedaan urutan dijelaskan?
Informasi tambahan diambil dari komentar:
Tidak ada pesanan oleh. Haruskah indeks yang tidak berkerumun menegakkan pesanan?
Kueri masih mengembalikan urutan yang berbeda bahkan saat menggunakan petunjuk indeks yang menentukan indeks yang dikelompokkan. Haruskah mereka Saya bertanya-tanya mengapa
nolock
mengubah urutan catatan yang dikembalikan tanpa perubahan rencana yang terlihat.Saya melakukan WinDiff pada mereka - sama kecuali untuk [
(nolock)
petunjuk].
Jawaban:
Munculnya set hasil yang dipesan, tanpa
ORDER BY
klausa, seringkali merupakan hasil dari pemindaian baris pencarian dalam urutan indeks. Salah satu alasan mengapa pemindaian indeks-urutan umumnya dipilih di bawahREAD COMMITTED
tingkat isolasi default adalah bahwa hal itu mengurangi kemungkinan anomali konkurensi yang tidak diinginkan seperti menemukan baris yang sama beberapa kali, atau sepenuhnya melewatkan beberapa baris. Ini dirinci di beberapa tempat, termasuk dalam seri artikel ini tentang tingkat isolasi.Dengan
NOLOCK
petunjuk tabel, perilaku ini santai, dan akses ke tabel dilakukan di bawahREAD UNCOMMITTED
tingkat isolasi yang lebih toleran , yang dapat memindai data dalam urutan alokasi alih-alih urutan indeks. Seperti yang dijelaskan dalam tautan itu, keputusan tentang apakah akan menggunakan pemindaian alokasi atau urutan indeks diserahkan ke mesin penyimpanan. Pilihan ini dapat berubah di antara eksekusi tanpa perubahan dalam rencana kueri .Ini mungkin terdengar sangat abstrak, tetapi dapat lebih mudah ditunjukkan dengan beberapa permintaan menggunakan fungsi tidak berdokumen terhadap database AdventureWorks2012 .
Pertanyaan dipinjam dengan sedikit modifikasi dari Paul White .
Akhirnya, hanya untuk menjadi jelas, jawaban ini adalah tentang penampilan set hasil yang dipesan. Tidak ada jaminan presentasi tanpa tingkat atas
ORDER BY
.Pemindaian urutan alokasi dapat terjadi dalam berbagai keadaan lain, seperti ketika kunci tingkat tabel diperoleh, atau database dalam mode read-only. Paralelisme juga dapat memengaruhi urutan data yang dikembalikan. Poin utamanya adalah bahwa tanpa
ORDER BY
, urutan data yang dikembalikan dapat bervariasi dari waktu ke waktu menurut desain.sumber
... maka Anda seharusnya tidak mengharapkan pesanan apa pun. Bahkan kueri yang sama berjalan beberapa kali bisa kembali dalam urutan berbeda tanpa peringatan. Alasannya adalah bahwa dua kueri Anda - yang merupakan kueri "berbeda" kemungkinan besar karena teks kueri yang berbeda, bukan karena petunjuknya - memiliki rencana eksekusi yang berbeda (dan perbedaannya mungkin tidak kentara, seperti iterator yang terlihat sama di keduanya rencana, tetapi
ordered: true
hanya memiliki satu, atau jumlah baris perkiraan yang sangat berbeda karena satu dikompilasi sebelum perubahan data utama). Bisa juga pemindaian urutan alokasi sedang dilakukan, seperti yang dijabarkan James dengan tepat dalam jawabannya.Dalam kasus apa pun, karena Anda menjalankan kueri tanpa
ORDER BY
, SQL Server menyimpulkan bahwa Anda tidak peduli tentang pesanan, sehingga berbunyi dan menentukan cara paling efisien untuk mengembalikan baris (tidak peduli tentang pesanan jika Anda tidak ).Biarkan saya memperjelas hal ini:
Jika Anda menginginkan atau mengharapkan pesanan tertentu, tambahkan klausa ORDER BY
Ini telah muncul sebelumnya:
Dan saya sudah membuat blog tentang itu:
Berikut adalah kutipan dari yang terakhir yang mengulangi apa yang saya katakan untuk menanggapi komentar Anda tentang menggunakan petunjuk indeks alih-alih
ORDER BY
klausa:Conor Cunningham - seorang pria yang cukup pintar, bertanggung jawab langsung atas sebagian besar yang dilakukan SQL Server ketika memproses kueri untuk Anda - juga membuat blog tentang hal itu di sini:
Silakan membaca dan menambahkan
ORDER BY
klausa ke pertanyaan Anda sebelum mengeluh tentang penyortiran yang berbeda atau tidak terduga.sumber
James dengan baik menjelaskan bagaimana ini bekerja, tetapi saya hanya ingin mengulangi satu hal: kecuali jika Anda menggunakan fungsi pemesanan, urutan baris dalam set hasil tidak ditentukan . Jika Anda membutuhkan pemesanan tertentu, gunakan
order by
klausa eksplisit - jika Anda tidak menentukannya, Anda pada dasarnya mengatakan "Saya sama sekali tidak peduli dengan pesanan", bukan "Memesannya dengan indeks berkerumun".sumber