Question

J'ai une table avec au moins un million de disques en elle. Ces lignes ont été créées par une application personnalisée qui lit plusieurs collections de sites SharePoint et stocke les urls d'éléments dans le tableau. Maintenant, puisque nous lisons les collections de sites d'une manière série, quelques premiers milliers de lignes appartiennent à la première collection de sites, quelques milliers appartiennent à la deuxième collection de sites, et ainsi de suite.

J'ai une autre application qui lit cette table de manière séquentielle. Cependant, cette façon je finis par l'envoi de requêtes HTTP à la même collection de sites pour un temps plus long.

Je sais que je pourrais obtenir des résultats aléatoires de la table dans ma seconde application. Mais, ce n'est pas une option. Je ne peux pas changer la façon dont la deuxième application fonctionne.

Maintenant, la question est: Comment puis-je prendre toutes les lignes de la table, shuffule les et rangez-le dans la table

Mise à jour: SQL Server 2008 R2 est ma base de données serveur

Était-ce utile?

La solution

Si l'application appelant met explicitement un ordre particulier dans sa requête (si vous utilisez MSSQL, vous pouvez le vérifier en ayant une session de profileur en cours d'exécution tandis que l'application fait son travail, d'autres DMBSs auront des options de journalisation similaires) puis il y a rien que vous pouvez faire et si ce n'est pas vous ne pouvez pas complètement garantir un ordre particulier.

Si aucune clause ORDER BY explicite est donnée alors les données sortiront dans un ordre qui est officiellement « non défini » - ce sera ce que jamais commander les découvertes les plus convineint du serveur. Pour une seule table requête ce sera très probablement l'ordre de la clé primaire. Dans MSSQL si vous avez un index ordonné en clusters les résultats se présenteront très probablement dans cet ordre pour une requête de table unique. Pour les requêtes multi-tables, il est coupé encore moins clair que cela dépend dans quel sens autour des droits incorporels planificateur de requêtes aller pour obtenir vos résultats (qui, sans indicateurs d'index explicites peuvent varier au fil du temps que l'équilibre des données dans les tableaux, selon les estimations du index statistiques du serveur conserve, change).

Si la table n'a pas d'index cluster ou une clé primaire, les données sont susceptibles de venir dans un ordre arbitraire de similaire à l'ordre les données ont été insérées. Dans ce cas, vous pouvez essayer:

SELECT * INTO temp_table FROM table_to_be_reordered
DELETE table_to_be_reordered
INSERT table_to_be_reordered SELECT * FROM temp_table ORDER BY NEWID()

ou cela peut être plus rapide

INSERT table_to_be_reordered SELECT * FROM temp_table ORDER BY NEWID()
DROP TABLE table_to_be_reordered
EXEC sp_rename 'temp_table', 'table_to_be_reordered'

Dans ce qui précède NEWID () est la fonction de MSSQL pour retourner un UUID et il utilise au hasard plutôt que des ID séquentiels par défaut - dans d'autres DMBSs vous devriez trouver une fonction similaire que vous pouvez utiliser. Soyez prudent avec votre choix de la fonction: par exemple sous MSSQL la fonction RAND () est evaulated une fois par requête, pas une seule fois par ligne, donc SELECT * FROM somewhere ORDER BY RAND() aurait pas l'effet desited (vous pouvez voir pourquoi en exécutant quelque chose comme SELECT RAND(), * FROM some_table)

Si vous utilisez MSSQL (votre question n'a pas état que vous SGBD ciblez) et ne pas déjà avoir un index ordonné en clusters sur la table, et soit une colonne suffisamment aléatoire (une colonne UUID par exemple) ou pourrait ajouter un sans perturber l'application d'appel, vous pouvez créer un index ordonné en clusters sur ce qui serait plus rapide que le SELECT INTO / DELETE / SELECT INTO ci-dessus. Mais encore une fois. Cela aura pas d'effet du tout si l'application demande explicitement les résultats dans un ordre particulier et ne peut avoir aucun effet de toute façon sinon

Autres conseils

Vous ne spécifiez pas quelle base de données mais dans Oracle, vous pouvez le faire par:

CREATE TABLE RAND_TABLE AS (SELECT * FROM ORIG_TABLE ORDER BY DBMS_RANDOM.RANDOM());

Vous aurez besoin d'assez d'espace dans votre tablespace TEMP pour faire face au tri. Ensuite, si vous le souhaitez, vous pouvez renommer les tables ORIG_TABLE et RAND_TABLE pour les intervertir. Je ne pense pas qu'il est possible de mélanger une table « en place ».

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top