2009-11-10 4 views
2

J'ai une requête SQL SELECT qui retourne beaucoup de lignes, et je dois le diviser en plusieurs partitions. Par exemple, définissez les résultats max à 10000 et parcourez les lignes appelant la requête select time en augmentant le premier résultat (0, 10000, 20000). Toutes les requêtes sont effectuées dans la même transaction, et les données que mes requêtes récupèrent ne changent pas pendant le processus (d'autres données dans ces tables peuvent changer, cependant).Les résultats sont-ils déterministes si je partitionne une requête SQL SELECT sans ORDER BY?

Est-il autorisé à utiliser select tout simplement:

select a from b where... 

Ou dois-je utiliser pour par la sélection:

select a from b where ... order by c 

Pour être sûr que je vais obtenir toutes les des rangées? En d'autres termes, est-il garanti qu'une requête sans ordre retournera toujours les lignes dans le même ordre? L'ajout de l'ordre à la requête entraîne une baisse considérable des performances de la requête. J'utilise Oracle, si cela est important.

EDIT: Malheureusement, je ne peux pas profiter du curseur de défilement.

+2

* Toujours * utiliser la commande si vous souhaitez que votre jeu de données soit commandé. S'il y a un problème de performances, c'est un problème différent (vérifiez les index, examinez les plans d'exécution, etc.). – paxdiablo

+0

pour les performances: utilisez la colonne indexée pour la clause order by ou appliquez l'index à la colonne que vous souhaitez utiliser dans l'ordre par la clause – Saar

Répondre

2

Aucune garantie à moins d'avoir passé commande sur la requête externe.

Mauvais exemple SQL Server, mais les mêmes règles s'appliquent. Pas pour garantie même avec requête interne

SELECT 
    * 
FROM 
    (
    SELECT 
     * 
    FROM 
     Mytable 
    ORDER BY SomeCol 
    ) foo 
+0

Il ne peut pas être déterministe s'il y a des liens, même avec 'ORDER BY'. Donc, votre première phrase est incorrecte. –

3

Non, sans l'ordre par elle n'est pas garanti que la requête retournera TOUJOURS les lignes dans le même ordre.

+0

Même si la commande n'est pas garantie! Il pourrait y avoir des liens. –

5

La commande n'est définitivement pas garantie sans une clause order by, mais le fait que vos résultats soient déterministes (en dehors de la commande) dépend de la clause where. Par exemple, si vous avez une colonne d'identification unique et votre clause where inclus une gamme de filtres différents à chaque fois que vous accédez, alors vous auriez des résultats déterministes non classés, à savoir:

select a from b where ID between 1 and 100 
select a from b where ID between 101 and 200 
select a from b where ID between 201 and 300 

retournera tous les ensembles de résultats distincts , mais l'ordre ne serait aucunement garanti.

+0

vous pouvez obtenir un équivalent 'LIMIT' déterministe [en utilisant SQL: caractéristiques de 2011] (http://www.sigmod.org/publications/sigmod-record/1203/pdfs/10.industry.zemke.pdf). recherche de 'WITH TIES'. –

1

Utilisez Limit

Alors vous feriez:

SELECT * FROM table ORDER BY id LIMITE 0100
SELECT * FROM table ORDER BY id LIMIT 101,100
SELECT * FROM table ORDER BY id LIMIT 201,100

La limite serait à partir de quelle position vous voulez commencer et la deuxième variable serait le nombre de résultats que vous voulez voir.
C'est une bonne astuce de pagnation.

Questions connexes