newid () / order by จะทำงานได้ แต่จะมีราคาแพงมากสำหรับชุดผลลัพธ์ขนาดใหญ่เพราะต้องสร้างรหัสสำหรับทุกแถวแล้วเรียงลำดับ
TABLESAMPLE () เป็นสิ่งที่ดีจากจุดยืนด้านประสิทธิภาพ แต่คุณจะได้รับผลลัพธ์จำนวนมาก (แถวทั้งหมดในหน้าจะถูกส่งคืน)
สำหรับตัวอย่างสุ่มจริงที่มีประสิทธิภาพดีกว่าวิธีที่ดีที่สุดคือกรองแถวแบบสุ่ม ฉันพบตัวอย่างโค้ดต่อไปนี้ในบทความ SQL Server Books Online การจำกัด ชุดผลลัพธ์โดยใช้ TABLESAMPLE :
หากคุณต้องการตัวอย่างแบบสุ่มของแต่ละแถวให้ปรับเปลี่ยนแบบสอบถามเพื่อกรองแถวแบบสุ่มแทนที่จะใช้ TABLESAMPLE ตัวอย่างเช่นแบบสอบถามต่อไปนี้ใช้ฟังก์ชัน NEWID เพื่อส่งกลับประมาณร้อยละหนึ่งของแถวของตาราง Sales.SalesOrderDetail:
SELECT * FROM Sales.SalesOrderDetail
WHERE 0.01 >= CAST(CHECKSUM(NEWID(),SalesOrderID) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)
คอลัมน์ SalesOrderID จะรวมอยู่ในนิพจน์ CHECKSUM เพื่อให้ NEWID () ประเมินหนึ่งครั้งต่อแถวเพื่อให้ได้การสุ่มตัวอย่างตามแต่ละแถว นิพจน์ CAST (CHECKSUM (NEWID (), SalesOrderID) & 0x7fffffff AS float / CAST (0x7fffffff AS AS) ประเมินค่าเป็นทศนิยมแบบสุ่มระหว่าง 0 และ 1
เมื่อทำงานกับตารางที่มี 1,000,000 แถวนี่คือผลลัพธ์ของฉัน:
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
หากคุณสามารถใช้งาน TABLESAMPLE ได้มันจะให้ประสิทธิภาพที่ดีที่สุดแก่คุณ มิฉะนั้นใช้วิธี newid () / filter newid () / คำสั่งซื้อควรเป็นทางเลือกสุดท้ายหากคุณมีชุดผลลัพธ์จำนวนมาก