5 votes

100k Rows retournés dans un ordre aléatoire, sans time out SQL s'il vous plaît

Ok,

J'ai beaucoup lu sur le retour d'un ensemble de rangées aléatoires l'année dernière, et la solution que nous avons trouvée est la suivante

ORDER BY newid()

Cela convient pour les rangs de moins de 5 000. Mais lorsque nous obtenons >10-20k lignes, nous obtenons des time outs SQL, l'exécution planifiée me dit que 76% du coût de ma requête provient de cette ligne. et la suppression de cette ligne augmente la vitesse d'un ordre de grandeur lorsque nous avons une grande quantité de lignes.

Nos utilisateurs ont besoin de traiter jusqu'à 100 000 lignes à la fois de cette manière.

Pour vous donner un peu plus de détails.

Nous disposons d'un tableau contenant 2,6 millions de codes alphanumériques à 4 chiffres. Nous utilisons un ensemble aléatoire de ces codes pour entrer dans un lieu. Par exemple, si nous organisons un événement d'une capacité de 5 000 personnes, un ensemble aléatoire de 5 000 de ces codes sera tiré de la table et remis à chaque client sous forme de code-barres, puis l'application de lecture de codes-barres à l'entrée aura la même liste de 5 000. La raison de l'utilisation d'un code alphanumérique à 4 chiffres (et non d'un numéro stupidement long comme un GUID) est qu'il est facile pour les gens de noter le numéro (ou de l'envoyer par SMS à un ami) et de l'apporter pour le faire entrer manuellement, donc nous ne voulons pas d'une grande quantité de caractères. Les clients adorent la dernière partie.

Y a-t-il un meilleur moyen que ORDER BY newid() ou existe-t-il un moyen plus rapide d'obtenir 100 000 lignes aléatoires à partir d'une table de 2,6 millions de lignes ?

Oh, et nous utilisons MS SQL 2005.

Merci,

Jo

0voto

Josef Richberg Points 488

Avez-vous essayé d'utiliser % (modulo) sur une colonne int donnée ? Je ne sais pas quelle est la structure de votre table, mais vous pourriez faire quelque chose comme ceci :

s de votre_table où CAST((CAST(ASCII(SUBSTRING(venuecode,1,1))) as varchar(3))+ CAST(ASCII(SUBSTRING(venuecode,2,1))as varchar(3))+ CAST(ASCII(SUBSTRING(venuecode,3,1))as varchar(3))+ CAST(ASCII(SUBSTRING(venuecode,4,1))as varchar(3))) as bigint) % 500000 entre 0 et 50000

Le code ci-dessus prendra tous vos lieux alphanumériques et les convertira en un nombre entier, puis divisera la table entière en 500.000 buckets, dont vous prendrez les 50000 premiers qui tombent entre 0 et 50000. Vous pouvez jouer avec le nombre après le % depuis (500 000) et vous pouvez jouer avec l'intervalle. Cela devrait rendre le processus aléatoire pour vous. Je ne sais pas si la clause where vous permettra d'améliorer les performances, mais cela vaut la peine d'essayer. En outre, sans ordre par, il n'y a aucune garantie de l'ordre (si vous avez plusieurs cpus et threading).

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