Oracle Pagination: Analyse de la fonction ROW_NUMBER() VS ROWNUM
Lors de la Pagination doit être fait dans un site web... la méthode la plus performante?
Analytique de la fonction ROW_NUMBER()
- Oracle 10G
-
http://www.oracle.com/technetwork/issue-archive/2007/07-jan/o17asktom-093877.html
SELECT columnA, columnB FROM (SELECT columnA, columnB, row_number() over (order by columnB) rn FROM table) WHERE rn BETWEEN LOW_LIMIT AND OFFSET;
ROWNUM
- http://www.oracle.com/technetwork/issue-archive/2007/07-jan/o56asktom-086197.html
-
INMHO je trouve cette approche plus lisible le code
SELECT * FROM ( SELECT rownum rn, a.* FROM( SELECT columnA, columnB FROM table ORDER BY columnB ) a WHERE rn <= OFFSET ) WHERE rnum >= LOW_LIMIT
-
Remarque: je comprends qu'il y a de RANG et DENSE_RANK fonctions analytiques, mais supposons, j'ai juste besoin d'une page d'déterministe requêtes.
-
Note 2: Pour récupérer le montant total de dossiers je pense en utilisant un simple requête count(*)
-
- Combien de lignes vous occupez-vous? A u vérifier expliquer le plan?
- double possible de Comment puis-je accélérer row_number dans Oracle?
- Essayez de charger une table de test avec une énorme quantité de données et de tester à la fois contre elle, et voila, vous avez votre réponse qui est (en conséquence du fait que vous avez exécuté le test vous-même) sur mesure directement le matériel/réseau/environnement, vous êtes en cours d'exécution.!
- maintenant que vous le dites... la réponse à cette question a un excellent article lien.
- Bon pointage dans les tests HW/Net/Environnement.
Vous devez vous connecter pour publier un commentaire.
Je pensais que cette question est intéressante, alors j'ai essayé un peu les choses.
J'ai table appelée large_t, qui contient environ 1,1 M lignes.
Alors j'ai deux questions:
Et
Si vous regardez les plans de deux requêtes génèrent, la première a une opération:
Tandis que l'analyse de la requête contient une opération appelée
L'ORDRE de TRI PAR STOPKEY est plus efficace en opération de tri qu'un simple ORDER BY. Je ne suis pas sûr de savoir comment une FENÊTRE de TRI POUSSÉ RANG fonctionne, mais il semble fonctionner dans un mode similaire.
Regarder v$sql_workarea après l'exécution de deux requêtes, les deux ne demandait qu'une sort_area de 4096 octets.
En revanche, si j'ai exécuté la requête sans pagination requête:
Alors le tri surface nécessaire est de 37M, prouvant de la sorte dans les deux requêtes est d'environ la même.
Normalement, si vous voulez efficacement retour le TOP N d'une requête triée, vous voulez un index sur la colonne de tri - prévenir Oracle devoir de tri à tous. Donc, j'ai créé un index sur OBJECT_ID, puis explique à la fois les requêtes de nouveau.
Ce temps, le premier de requête utilisé l'index et retourné en 0,2 secondes, tandis que la deuxième requête n'utilisez pas le nouvel indice et a été beaucoup plus lent.
Donc ma conclusion de ce rapide peu d'analyse, c'est que dans le cas général à l'aide de rownum de filtrer ou de l'analytique de la fonction row_number à la fois un rendement à peu près la même. Cependant, la rownum exemple lancé automatiquement à l'aide de l'index j'ai créé sur la table lorsque la fonction row_number n'a pas. Peut-être que je pourrais l'obtenir pour utiliser l'index, avec quelques notes - qui est quelque chose que vous pouvez expérimenter avec.
À l'écart des autres différences mentionnées dans les réponses, vous devez également prendre en compte les performances. Il y a un non-autoritaire, mais très intéressant rapport ici, en comparant les différents moyens de pagination, parmi lesquelles l'utilisation de
ROWNUM
par rapport àROW_NUMBER() OVER()
:https://web.archive.org/web/20160901191310/http://www.inf.unideb.hu:80/~gabora/pagination/results.html
Pour générer vos propres résultats empiriques:
Bien sûr, vous pouvez augmenter la taille de la table en fonction de vos fins de test!
Définir la durée et à exécuter deux requêtes contre la grande table.
Modifier la structure de la table en fonction de vos test que vous voudrez peut-être une des colonnes indexée en fonction de votre requête trop etc. mais essentiellement c'est un test simple et ne vous prendra pas de temps à s'exécuter.
Si les deux sortent à peu près les mêmes timings puis utilisez le plus lisible (et donc supportable) version.