Memilih baris acak selalu rumit, dan tidak ada solusi sempurna yang tidak melibatkan kompromi. Baik kompromi kinerja, atau kompromi distribusi acak, atau kompromi pada kemungkinan memilih duplikat, dll.
Seperti yang disebutkan @JakeGould, solusi apa pun dengan ORDER BY RAND()
tidak skala dengan baik. Karena jumlah baris di tabel Anda semakin besar, biaya pengurutan seluruh tabel dalam filesort semakin buruk. Jake benar bahwa kueri tidak dapat di-cache ketika urutan pengurutan acak. Tapi saya tidak terlalu peduli tentang itu karena saya biasanya menonaktifkan cache kueri (ini memiliki masalah skalabilitasnya sendiri).
Berikut adalah solusi untuk melakukan pra-acak baris dalam tabel, dengan membuat kolom rownum dan menetapkan nilai unik berurutan:
ALTER TABLE products ADD COLUMN rownum INT UNSIGNED, ADD KEY (rownum);
SET @rownum := 0;
UPDATE products SET rownum = (@rownum:[email protected]+1) ORDER BY RAND();
Sekarang Anda bisa mendapatkan baris acak dengan pencarian indeks, tanpa menyortir:
SELECT * FROM products WHERE rownum = 1;
Atau Anda bisa mendapatkan baris acak berikutnya:
SELECT * FROM products WHERE rownum = 2;
Atau Anda bisa mendapatkan 10 baris acak sekaligus, atau nomor lain yang Anda inginkan, tanpa duplikat:
SELECT * FROM products WHERE rownum BETWEEN 11 and 20;
Anda dapat mengacak ulang kapan saja Anda mau:
SET @rownum := 0;
UPDATE products SET rownum = (@rownum:[email protected]+1) ORDER BY RAND();
Masih mahal untuk melakukan penyortiran acak, tetapi sekarang Anda tidak perlu melakukannya pada setiap kueri SELECT. Anda dapat melakukannya sesuai jadwal, semoga di luar jam sibuk.