ฉันจะใช้ตัวอย่างสุ่มอย่างง่ายที่มีประสิทธิภาพใน SQL ได้อย่างไร ฐานข้อมูลที่เป็นปัญหากำลังเรียกใช้ MySQL ตารางของฉันมีอย่างน้อย 200,000 แถวและฉันต้องการตัวอย่างสุ่มอย่างง่ายประมาณ 10,000
คำตอบที่ "ชัดเจน" คือ:
SELECT * FROM table ORDER BY RAND() LIMIT 10000
สำหรับตารางขนาดใหญ่มันช้าเกินไปมันเรียกRAND()
ทุกแถว (ซึ่งวางไว้ที่ O (n)) แล้วเรียงลำดับทำให้เป็น O (n lg n) ได้ดีที่สุด มีวิธีทำเร็วกว่า O (n) หรือไม่?
หมายเหตุ : ในฐานะที่เป็นแอนดรูเหมาชี้ให้เห็นในความคิดเห็นที่หากคุณใช้วิธีการนี้ใน SQL Server คุณควรใช้ฟังก์ชั่น T-SQL NEWID()
เพราะ RAND () อาจจะกลับมาเป็นค่าเดียวกันสำหรับทุกแถว
แก้ไข: 5 ปีต่อมา
ฉันพบปัญหานี้อีกครั้งด้วยตารางที่ใหญ่กว่าและลงเอยด้วยการใช้โซลูชันของ @ ignorant เวอร์ชันที่มีการปรับแต่งสองอย่าง:
- สุ่มตัวอย่างแถวเป็น 2-5x ขนาดตัวอย่างที่ฉันต้องการเพื่อราคาถูก
ORDER BY RAND()
- บันทึกผลลัพธ์ของ
RAND()
คอลัมน์ที่จัดทำดัชนีในทุกการแทรก / อัปเดต (หากชุดข้อมูลของคุณไม่ได้อัปเดตมากนักคุณอาจต้องหาวิธีอื่นในการทำให้คอลัมน์นี้ใหม่อยู่เสมอ)
ในการรับตัวอย่างตาราง 1,000 รายการฉันนับแถวและสุ่มตัวอย่างผลลัพธ์โดยเฉลี่ย 10,000 แถวด้วยคอลัมน์ frozen_rand:
SELECT COUNT(*) FROM table; -- Use this to determine rand_low and rand_high
SELECT *
FROM table
WHERE frozen_rand BETWEEN %(rand_low)s AND %(rand_high)s
ORDER BY RAND() LIMIT 1000
(การนำไปใช้งานจริงของฉันเกี่ยวข้องกับการทำงานมากขึ้นเพื่อให้แน่ใจว่าฉันไม่ได้ขีดล่างและต้องพัน rand_high ด้วยตนเอง แต่แนวคิดพื้นฐานคือ "สุ่มตัด N ของคุณให้เหลือไม่กี่พัน")
แม้ว่าสิ่งนี้จะทำให้เสียสละ แต่ก็ช่วยให้ฉันสามารถสุ่มตัวอย่างฐานข้อมูลโดยใช้การสแกนดัชนีจนกว่าจะมีขนาดเล็กพอที่จะORDER BY RAND()
อีกครั้ง
RAND()
ส่งคืนค่าเดียวกันทุกครั้งที่โทรตามมา