Pradeep Adiga'nın ilk önerisi,, ORDER BY NEWID()
gayet iyi ve geçmişte bu sebepten kullandığım bir şey.
Kullanırken dikkatli olun RAND()
- birçok bağlamda, her ifade için yalnızca bir kez yürütülür, bu nedenle ORDER BY RAND()
herhangi bir etkisi olmaz (her satır için RAND'dan () aynı sonucu elde ettiğiniz için).
Örneğin:
SELECT display_name, RAND() FROM tr_person
kişi tablomuzdaki her adı ve her satır için aynı olan "rasgele" bir sayı döndürür. Sayı, sorguyu her çalıştırdığınızda değişebilir, ancak her satırda her satır için aynıdır.
Aynı maddenin RAND()
bir ORDER BY
cümlede kullanılan durum olduğunu göstermek için şunu deniyorum:
SELECT display_name FROM tr_person ORDER BY RAND(), display_name
Sonuçlar, daha önceki sıralama alanının (rastgele olması beklenen) etkisinin olmadığını belirten adla hala sıralanmıştır, bu nedenle muhtemelen her zaman aynı değere sahiptir.
Tarafından Sipariş NEWID()
NEWID () değildi çünkü eğer, iş olsa yapar hep yeniden değerlendirilmesi UUID amacı dökümü yapılır benzersiz tanımlayıcılar ile bir statemnt birçok yeni satırlar eklerken onlar anahtar, yani:
SELECT display_name FROM tr_person ORDER BY NEWID()
yok "rastgele" isimleri sipariş.
Diğer DBMS
Yukarıdakiler MSSQL için geçerlidir (en azından 2005 ve 2008 ve 2000'i de doğru hatırlıyorsam). Yeni bir UUID dönen bir fonksiyon olmalıdır tüm DBMSs NewID (her zaman değerlendirilecektir) MSSQL altında ama ve / veya kendi testlerle belgelerinde bu doğrulayarak değer. RAND () gibi diğer rasgele sonuç fonksiyonlarının davranışının DBMS'ler arasında değişme olasılığı daha yüksektir, bu nedenle dokümanları tekrar kontrol edin.
Ayrıca, UUID değerlerine göre sıralamanın, bazı tiplerde DB tipinin anlamlı bir sıralamaya sahip olmadığını varsaydığı gibi göz ardı edildiğini de gördüm. Bunu bu durumda bulursanız, açıkça UUID'yi sıralama cümlesinde bir dize türüne aktarın veya CHECKSUM()
SQL Server'daki gibi başka bir işlevi etrafına sarın (bu işlemden sonra yapılacak gibi küçük bir performans farkı olabilir. 128 bitlik olmayan bir 32 bitlik değerler olsa da, bunun yararı CHECKSUM()
ilk önce değer başına çalıştırmanın maliyetinden ağır basıp basmadığıdır .
Kenar notu
İsteğe bağlı ancak biraz tekrarlanabilir bir sipariş istiyorsanız, satırların içindeki verilerin kontrolsüz bir alt kümesine göre sipariş verin. Örneğin ya bunlar ya da bunlar, isimleri keyfi fakat tekrarlanabilir bir sıra ile döndürür:
SELECT display_name FROM tr_person ORDER BY CHECKSUM(display_name), display_name -- order by the checksum of some of the row's data
SELECT display_name FROM tr_person ORDER BY SUBSTRING(display_name, LEN(display_name)/2, 128) -- order by part of the name field, but not in any an obviously recognisable order)
İsteğe bağlı ancak yinelenebilir siparişler, uygulamalarda genellikle yararlı değildir, ancak çeşitli siparişler üzerinde bazı kodlar üzerinde test yapmak istiyorsanız, ancak her bir çalışmayı birkaç kez aynı şekilde tekrarlayabilmek istiyorsanız (ortalama zamanlamayı almak için) Birkaç çalıştırma sonucu elde edilen sonuçlar veya koda yaptığınız bir düzeltmenin daha önce belirli bir giriş sonucu tarafından vurgulanan bir sorunu veya verimsizliği ortadan kaldırdığını veya sadece kodunuzun "kararlı" olduğunu test etmek için her seferinde aynı sonucu döndürdüğünü test etmek aynı veriyi verilen bir siparişte gönderilirse).
Bu numara, kendi gövdeleri içerisinde NEWID () gibi deterministik olmayan çağrılara izin vermeyen fonksiyonlardan daha keyfi sonuçlar elde etmek için de kullanılabilir. Yine, bu gerçek dünyada sıklıkla yararlı olabilecek bir şey değildir, ancak eğer bir işlevi rastgele bir şey döndürmek istiyorsanız ve "rastgele-ish" yeterince iyi ise (kullanışlı olan kuralları hatırlamaya dikkat edin) kullanışlı olabilir. kullanıcı tanımlı fonksiyonlar değerlendirildiğinde, yani genellikle her satırda yalnızca bir kez, veya sonuçlarınız beklediğiniz / ihtiyaç duyduğunuz olmayabilir).
performans
EBarr'ın işaret ettiği gibi, yukarıdakilerden herhangi birinde performans sorunları olabilir. Birkaç satırdan fazla için, istenen satır sayısı doğru sırayla okunmadan önce çıktının tempdb'ye biriktirilmiş olduğunu görmek için garanti altına alınacaksınız; bu, ilk 10'u aramanıza rağmen tam bir dizin bulabileceğiniz anlamına gelir tarama (veya daha kötüsü tablo taraması), tempdb'ye çok büyük bir yazı bloğu ile birlikte gerçekleşir. Bu nedenle, çoğu şeyi olduğu gibi, bunu üretimde kullanmadan önce gerçekçi verilerle kıyaslama yapmak hayati önem taşıyabilir.