2012-05-12 4 views
4

J'ai retenu poser car je pense que cette question est posée tant, mais manque encore une réponse définitive:MySQL aléatoire avec des écarts de plus de 40 millions de lignes

Objets tableau: 40M + lignes rempli d'UPC, EIN, ISBN en tant que clé primaire obj_id. Gaps

* Table Obj_Cat *: Lier des objets à des catégories. Colonnes de | obj_id | cat_id |

Question: Quelle est la meilleure façon de retourner 5 obj_id aléatoire non-séquentiel? Y at-il un meilleur moyen que ce que j'ai énuméré?

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; Run 5 fois

  • très lent avec de grandes tables.

Solution2: objets SELECT obj_id FROM objects WHERE obj_id >= (SELECT FLOOR(MAX(obj_id) * RAND()) FROM) LIMIT 1; Run 5 fois (ne comprennent pas obj_cat rejoindre pour le garder plus facilement comprise)

  • La meilleure solution si vos lignes sont ou ont des lacunes gapless négligeables. Très vite. 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 Run 5 fois

  • Très flexible. Beaucoup plus rapide que la solution 1. Fonctionne avec des lacunes. Mais à 40M + lignes, un seul 'LIMIT $ offset, 1' peut encore prendre 1 min.

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

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

  • assez rapide, prend environ 45 secondes par catégorie, mais retourne 5 résultats non séquentielles sur rendez-vous.

Y a-t-il un meilleur moyen que les gens ont découvert en traitant de grands ensembles de données? Je sais que cela semble être une question en double, mais je pensais que je contribuerais mes expériences avec une table de 40M +.

Répondre

0

Avec un ensemble de données de cette taille, vous ne pouvez pas faire des calculs à la volée comme celui-ci. Vous devez profiter du compromis temps-mémoire. Créez une nouvelle colonne d'index d'entier non signé dans votre table obj_cat avec une largeur supérieure à votre nombre maximal de lignes et remplissez chaque ligne avec un nombre aléatoire. De cette façon, vous pouvez simplement générer un nombre aléatoire et sélectionner directement la correspondance la plus proche cinq fois. Ce sera plusieurs ordres de grandeur plus rapide que d'essayer d'utiliser un ORDER BY RAND().

+0

Je comprends ce concept, mais cela ne fonctionnera pas si je veux sélectionner des valeurs aléatoires avec une catégorie particulière, sauf si j'ai une table pour chaque catégorie avec int int. Et donné plus de 2000 catégories je n'aime pas l'idée de plus de 2000 tables. Plus un objet donné peut avoir plusieurs catégories. –

+0

@AnthonyLin - Pouvez-vous garder le category_id dans la table avec la table des ints aléatoires? –

Questions connexes