newid () / order by akan bekerja, tetapi akan sangat mahal untuk set hasil besar karena harus menghasilkan id untuk setiap baris, dan kemudian mengurutkannya.
TABLESAMPLE () bagus dari sudut pandang kinerja, tetapi Anda akan mendapatkan hasil yang berkelompok (semua baris pada halaman akan dikembalikan).
Untuk sampel acak benar yang berkinerja lebih baik, cara terbaik adalah menyaring baris secara acak. Saya menemukan contoh kode berikut dalam artikel SQL Server Books Online yang Membatasi Set Hasil dengan Menggunakan TABLESAMPLE :
Jika Anda benar-benar ingin sampel acak baris individual, ubah kueri Anda untuk memfilter baris secara acak, alih-alih menggunakan TABLESAMPLE. Misalnya, kueri berikut ini menggunakan fungsi NEWID untuk mengembalikan sekitar satu persen dari baris tabel Sales.SalesOrderDetail:
SELECT * FROM Sales.SalesOrderDetail
WHERE 0.01 >= CAST(CHECKSUM(NEWID(),SalesOrderID) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)
Kolom SalesOrderID termasuk dalam ekspresi CHECKSUM sehingga NEWID () mengevaluasi satu kali per baris untuk mencapai pengambilan sampel berdasarkan per baris. Ekspresi CAST (CHECKSUM (NEWID (), SalesOrderID) & 0x7fffffff AS float / CAST (0x7fffffff AS int) mengevaluasi nilai float acak antara 0 dan 1.
Saat dijalankan melawan tabel dengan 1.000.000 baris, berikut ini adalah hasil saya:
SET STATISTICS TIME ON
SET STATISTICS IO ON
/* newid()
rows returned: 10000
logical reads: 3359
CPU time: 3312 ms
elapsed time = 3359 ms
*/
SELECT TOP 1 PERCENT Number
FROM Numbers
ORDER BY newid()
/* TABLESAMPLE
rows returned: 9269 (varies)
logical reads: 32
CPU time: 0 ms
elapsed time: 5 ms
*/
SELECT Number
FROM Numbers
TABLESAMPLE (1 PERCENT)
/* Filter
rows returned: 9994 (varies)
logical reads: 3359
CPU time: 641 ms
elapsed time: 627 ms
*/
SELECT Number
FROM Numbers
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), Number) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
Jika Anda bisa menggunakan TABLESAMPLE, itu akan memberi Anda kinerja terbaik. Kalau tidak, gunakan metode newid () / filter. newid () / order oleh harus menjadi pilihan terakhir jika Anda memiliki hasil yang besar.