4 votes

MySQL aléatoire avec des lacunes de 40+ millions de lignes

Je me suis retenu de poser cette question, car j'ai l'impression qu'elle est souvent posée, mais qu'il n'y a toujours pas de réponse définitive :

Objets table : 40M+ lignes remplies avec UPC, EIN, ISBN comme clé primaire obj_id. Lacunes

Table *Obj_Cat* : Lier les objets aux catégories. Les colonnes de | obj_id | cat_id |

Question : Quelle est la meilleure façon de renvoyer 5 obj_id non séquentiels et aléatoires ? Existe-t-il une meilleure méthode que celle que j'ai indiquée ?

Solution1 : SELECT objects.obj_id FROM objects left join obj_cat on objects.obj_id=obj_cat.obj_id WHERE obj_cat.cat_id=cat_id ORDER BY RAND() LIMIT 1; Courir 5 fois

  • Très lent avec les grandes tables.

Solution2 : SELECT obj_id FROM objects WHERE obj_id >= (SELECT FLOOR( MAX(obj_id) * RAND()) FROM objets ) LIMIT 1; Exécuté 5 fois (n'a pas inclus la jointure obj_cat pour que ce soit plus facile à comprendre)

  • C'est la meilleure solution si vos rangs sont sans espace ou ont des espaces négligeables. Très rapide.

  • Ne fonctionne pas bien avec les catégories, car il y aura inévitablement des lacunes dans la numérotation.

Solution3 : SELECT FLOOR(RAND() * COUNT(objects.*)) AS décalage FROM objects, obj_cat WHERE objects.obj_id=obj_cat.obj_id AND obj_cat.cat_id=cat_id; SELECT obj_id FROM objects LIMIT $offset, 1 Courir 5 fois

  • Très flexible. Beaucoup plus rapide que la solution 1. Fonctionne avec les écarts. Mais avec plus de 40 millions de lignes, un seul 'LIMIT $offset, 1' peut encore prendre 1 minute.

J'ai utilisé la solution 3, mais elle est lente. Ma solution actuelle est d'utiliser Solr randomsortfield, car il est facile de spécifier ma catégorie dans la fq.

Solution Solr : ?q=*&fl=obj_id&fq=cat:(cat_id)&sort=random_* desc&rows=5

  • Assez rapide, il prend environ 45 secondes par catégorie mais renvoie 5 résultats non séquentiels en une seule fois.

Y a-t-il une meilleure méthode que les gens ont découvert pour traiter de grands ensembles de données ? Je sais que cela semble être une question en double, mais j'ai pensé que je devais apporter mon expérience avec une table de plus de 40M.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X