Πώς μπορούμε να βελτιστοποιήσουμε τον χειριστή ORDER BY RAND();
sobes.tech AI
Απάντηση από AI
Η βελτιστοποίηση του ORDER BY RAND() είναι δύσκολη, καθώς απαιτεί πλήρη ανάκτηση δεδομένων για τη δημιουργία τυχαίου αριθμού για κάθε γραμμή. Οι τυπικές προσεγγίσεις:
-
Επιλογή τυχαίου αναγνωριστικού:
- Λήψη του αριθμού των γραμμών στον πίνακα.
- Δημιουργία τυχαίου αριθμού από 0 έως N-1 (ή 1 έως N).
- Επιλογή γραμμής με ανάλογη μετατόπιση ή
OFFSET.
SELECT COUNT(*) FROM your_table; -- Υποθέτουμε ότι το συνολικό_αριθμό_γραμμών = N SELECT * FROM your_table LIMIT 1 OFFSET floor(random() * N);Αυτή η μέθοδος ταιριάζει για επιλογή μιας ή λίγων τυχαίων γραμμών. Δεν είναι αποδοτική για μεγάλο αριθμό γραμμών.
-
Τυχαία επιλογή με εύρος
id:- Εύρεση του ελάχιστου και μέγιστου
id. - Δημιουργία τυχαίου αριθμού σε αυτό το εύρος.
- Επιλογή γραμμής με
id >= τυχαίος_αριθμός, χρησιμοποιώνταςLIMIT.
SELECT MIN(id), MAX(id) FROM your_table; -- Υποθέτουμε ότι έχουν ληφθεί min_id, max_id -- Στην εφαρμογή, δημιουργούμε τυχαίο id στο εύρος [min_id, max_id] -- Για παράδειγμα: τυχαίο_id = min_id + floor(random() * (max_id - min_id + 1)) SELECT * FROM your_table WHERE id >= τυχαίο_id LIMIT 1;Μπορεί να παραλείψει γραμμές αν υπάρχουν κενά στα
id. - Εύρεση του ελάχιστου και μέγιστου
-
Δημιουργία προσωρινού πίνακα ή χρήση υποερωτήματος με ταξινόμηση κατά τυχαίο αριθμό:
- Επιλογή υποσυνόλου δεδομένων ή μόνο
idσε υποερώτημα. - Εφαρμογή
ORDER BY RAND()σε αυτό το υποσύνολο.
SELECT * FROM your_table AS t1 JOIN (SELECT id FROM your_table ORDER BY RAND() LIMIT 100) AS t2 ON t1.id = t2.id;Μειώνει το φορτίο αν το
LIMITεφαρμόζεται στο υποερώτημα. - Επιλογή υποσυνόλου δεδομένων ή μόνο
-
Χρήση πρόσθετου πεδίου με τυχαίο αριθμό:
- Προσθήκη πεδίου στον πίνακα για αποθήκευση τυχαίου αριθμού.
- Περιοδική ενημέρωση αυτού του πεδίου για όλες τις γραμμές.
- Ταξινόμηση με βάση αυτό το πεδίο.
-- Προσθήκη πεδίου ALTER TABLE your_table ADD random_sort_key FLOAT; -- Περιοδική ενημέρωση UPDATE your_table SET random_sort_key = RAND(); -- Επιλογή SELECT * FROM your_table ORDER BY random_sort_key LIMIT 10;Απαιτεί αλλαγές στο σχήμα και διαδικασία φόντου ενημέρωσης.
-
Αλγόριθμος "ανακατάταξης" (Fisher-Yates) εκτός βάσης δεδομένων:
- Επιλογή όλων των
id(ή όλων των δεδομένων αν είναι μικρά). - Ανακατάταξη της λίστας στην εφαρμογή.
- Επιλογή των πρώτων N στοιχείων.
// Υποθέτουμε ότι, ids είναι []int // ids = ... // Ανάκτηση ids από τη βάση δεδομένων rand.Shuffle(len(ids), func(i, j int) { ids[i], ids[j] = ids[j], ids[i] }) // Τώρα τα πρώτα N στοιχεία του ids είναι τυχαία // Μπορείτε να τα χρησιμοποιήσετε για επιλογή πλήρων γραμμών // SELECT * FROM your_table WHERE id IN (...)Κατάλληλο μόνο για πίνακες με λίγες γραμμές.
- Επιλογή όλων των
Η επιλογή της βέλτιστης μεθόδου εξαρτάται από το μέγεθος του πίνακα, τον απαιτούμενο αριθμό τυχαίων γραμμών και το συγκεκριμένο σύστημα διαχείρισης βάσεων δεδομένων. Για τις περισσότερες περιπτώσεις, όπου χρειάζεται να επιλεγούν λίγες τυχαίες γραμμές από μεγάλο πίνακα, ο συνδυασμός λήψης id με επακόλουθο OFFSET ή WHERE id IN (...) θα είναι πιο αποδοτικός από το καθαρό ORDER BY RAND().