IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Oracle Discussion :

SELECT limité pour multipage web.


Sujet :

Oracle

  1. #1
    Membre confirmé Avatar de thanaos
    Inscrit en
    Mai 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 94
    Par défaut SELECT limité pour multipage web.
    Bonjour à tous zet à toutes.
    L'affichage multipage web nécessité par un nombre important de ligne de résultat pour un SELECT est on ne peut plus simple avec une sgbd comme MySQL est son option LIMIT. Pour Oracle cette option n'existe pas.
    Voici la technique que j'utilise le but étant d'avoir vos opinions et vos éventuelles solutions.
    (PHP4, Oracle9)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    query_origine =  "SELECT * FROM table1"
    Pour connaitre le nombre de pages à afficher, je dois connaitre le nombre de lignes d'où l'execution d'une première requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT count(*) FROM table1
    Il faut ensuite que je ne selectionne que les lignes nécessaires à l'affichage d'une page
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    query_affichage = "
    SELECT * FROM 
    	(
    	SELECT e.*, ROWNUM RN FROM ( ".$query_origine.") e 
    	) 
    	WHERE RN BETWEEN ".$premiere_ligne." AND ".$derniere_ligne;
    Auriez vous des remarques ou des solutions alternatives. Merci.
    nota : les variables sont précédées du signe $.

  2. #2
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967

  3. #3
    Membre confirmé Avatar de thanaos
    Inscrit en
    Mai 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 94
    Par défaut
    Bonjour Fred_D. Mes respects, Grand sage oraclien.
    J'ai un petit souci avec les explications de la page
    http://oracle.developpez.com/faq/?page=11#rankrownum.
    Comme dit dans la Faq : "Il faut donc trier les données avant qu'Oracle ne leur affecte un numéro", donc si ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SQL> SELECT ROWNUM, a.* 
    2 FROM ( 
    3 SELECT * 
    4 FROM emp 
    5 ORDER BY sal 
    6 ) a 
    7 WHERE ROWNUM < 5 ;
    est correct, cela ne peut pas l'être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT   * 
    FROM ( SELECT ROWNUM NUM, ename, job 
               FROM EMP ORDER BY sal
             ) 
    WHERE    NUM BETWEEN 1 AND 5 ;
    Ce que tu veux me dire c'est que ma technique est bonne ou qu'il n'y en a pas d'autres ?

  4. #4
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    oui c'est bon

    une alternative consiste à utiliser RANK()

  5. #5
    Membre confirmé Avatar de thanaos
    Inscrit en
    Mai 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 94
    Par défaut
    Merci.
    Dois je demander la modification de la Faq pour éviter les erreurs (ou plutôt les mauvaises interprétations ?

  6. #6
    Expert confirmé
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    SQL> SELECT   * 
      2  FROM ( SELECT ROWNUM NUM, ename, job, sal 
      3             FROM EMP ORDER BY sal
      4           ) 
      5  WHERE    NUM BETWEEN 1 AND 5 ;
           NUM ENAME      JOB              SAL
    ---------- ---------- --------- ----------
             1 SMITH      CLERK            900
             3 WARD       SALESMAN        1250
             5 MARTIN     SALESMAN        1250
             2 ALLEN      SALESMAN        1600
             4 JONES      MANAGER         2975
    SQL>
    ou est la problème avec cette requête ?

  7. #7
    Membre confirmé Avatar de thanaos
    Inscrit en
    Mai 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 94
    Par défaut
    Bonjour SheikYerbouti. Le code n'est pas en cause, c'est l'enchainement des explications qui me semble risqué.
    Pour ce qui est du rank() et peut être plutôt dense_rank() , la mise en oeuvre me parait être un tantiné plus complexe.

  8. #8
    Expert confirmé
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Par défaut
    La première ligne (SMITH) n'apparait plus.
    n'est-ce pas le but désiré ???

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SQL> SELECT   * 
      2  FROM ( SELECT ROWNUM NUM, ename, job, sal
      3             FROM EMP ORDER BY sal
      4           ) 
      5  WHERE    NUM BETWEEN 2 AND 5 ;
           NUM ENAME      JOB              SAL
    ---------- ---------- --------- ----------
             3 WARD       SALESMAN        1250
             5 MARTIN     SALESMAN        1250
             2 ALLEN      SALESMAN        1600
             4 JONES      MANAGER         2975
    SQL>

  9. #9
    Membre confirmé Avatar de thanaos
    Inscrit en
    Mai 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 94
    Par défaut
    Désolé. Je n'est pas été assez rapide pour modifier mon message.
    Le code n'est pas en cause, c'est l'enchainement des explications qui me semble risqué.

  10. #10
    Expert confirmé
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Par défaut
    Par contre, et concernant surtout les tables de forte volumétrie, il semble que la syntaxe suivante soit plus performante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SQL> SELECT f.*
      2  FROM ( SELECT e.*, ROWNUM r
      3         FROM (SELECT * FROM scott.parts) e
      4         WHERE ROWNUM <= 10) f
      5  WHERE f.r >= 1;

  11. #11
    Membre confirmé Avatar de thanaos
    Inscrit en
    Mai 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 94
    Par défaut
    Cela vient du BETWEEN ?

    (Euh pour la Faq, je fais rien ?)

  12. #12
    Expert confirmé
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Par défaut
    Dans le premier cas, on lit l'intégralité de la table depuis le début (même pour lire les dernières lignes), alors que le 2ème example s'affranchit de cette contrainte grâce aux clauses where.
    La différence n'apparait toutefois évidente qu'à partir d'une certaine volumétrie (ne me demandez pas laquelle ! fiez-vous aux EXPLAIN PLANS.)

  13. #13
    Membre confirmé Avatar de thanaos
    Inscrit en
    Mai 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 94
    Par défaut
    Donc sur une table de 100000 lignes si on veut les lignes de la 99001ième à la 99201ème (pour un multipage avec un pas de 200) le deuxième cas est plus rapide?
    Tel la fosse, je suis sceptique.

  14. #14
    Expert confirmé
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Par défaut
    Lorsque l'on doute, rien ne vaut le test et le jugement de l'explain plan. (ou tout simplement de ltemps de réponse de la requête).
    Douter pour douter n'amène nulle part.

  15. #15
    Expert confirmé
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
     
    SQL>
    SQL>
    SQL> SELECT f.*
      2  FROM ( SELECT e.*, ROWNUM r
      3         FROM (SELECT * FROM scott.parts) e
      4         WHERE ROWNUM <= 10) f
      5  WHERE f.r >= 1;
          1211 Part 1211                1
          1212 Part 1212                2
          1213 Part 1213                3
          1214 Part 1214                4
          1215 Part 1215                5
          1216 Part 1216                6
          1217 Part 1217                7
          1218 Part 1218                8
          1219 Part 1219                9
          1220 Part 1220               10
    10 ligne(s) sÚlectionnÚe(s).
    EcoulÚ : 00 :00 :00.01
    Plan d'exÚcution
    ----------------------------------------------------------
    Plan hash value: 235552802
    -----------------------------------------------------------------------------
    | Id  | Operation           | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    -----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |       |    10 |   350 |    10  (80)| 00:00:01 |
    |*  1 |  VIEW               |       |    10 |   350 |    10  (80)| 00:00:01 |
    |*  2 |   COUNT STOPKEY     |       |       |       |            |          |
    |   3 |    TABLE ACCESS FULL| PARTS |  1049K|    22M|    10  (80)| 00:00:01 |
    -----------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter("F"."R">=1)
       2 - filter(ROWNUM<=10)
    Note
    -----
       - dynamic sampling used for this statement
     
    Statistiques
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
              5  consistent gets
              0  physical reads
              0  redo size
            772  bytes sent via SQL*Net to client
            385  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             10  rows processed
    SQL>
    SQL>
    SQL>
    SQL>
    SQL>
    SQL>
    SQL>
    SQL>
    SQL>
    SQL>
    SQL>
    SQL> SELECT e.*
      2  FROM ( SELECT p.*, ROWNUM r FROM scott.parts p) e
      3  WHERE e.r between 1 and 10;
          1211 Part 1211                1
          1212 Part 1212                2
          1213 Part 1213                3
          1214 Part 1214                4
          1215 Part 1215                5
          1216 Part 1216                6
          1217 Part 1217                7
          1218 Part 1218                8
          1219 Part 1219                9
          1220 Part 1220               10
    10 ligne(s) sÚlectionnÚe(s).
    EcoulÚ : 00 :00 :00.41
    Plan d'exÚcution
    ----------------------------------------------------------
    Plan hash value: 4260190374
    -----------------------------------------------------------------------------
    | Id  | Operation           | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    -----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |       |  1049K|    35M|   697   (6)| 00:00:09 |
    |*  1 |  VIEW               |       |  1049K|    35M|   697   (6)| 00:00:09 |
    |   2 |   COUNT             |       |       |       |            |          |
    |   3 |    TABLE ACCESS FULL| PARTS |  1049K|    22M|   697   (6)| 00:00:09 |
    -----------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter("E"."R"<=10 AND "E"."R">=1)
    Note
    -----
       - dynamic sampling used for this statement
     
    Statistiques
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
           3023  consistent gets
              0  physical reads
              0  redo size
            772  bytes sent via SQL*Net to client
            385  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             10  rows processed
    SQL>

  16. #16
    Membre confirmé Avatar de thanaos
    Inscrit en
    Mai 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 94
    Par défaut
    Merci pour toute votre aide.
    Bonne journée

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2013] Types de données limités pour Access Web App
    Par RichardUW dans le forum Access
    Réponses: 0
    Dernier message: 03/07/2014, 19h32
  2. Votre langage de programmation serveur préféré pour le Web ?
    Par Marc Lussac dans le forum Général Conception Web
    Réponses: 82
    Dernier message: 18/02/2009, 17h50
  3. "LIMIT" pour Oracle ?
    Par aweb01 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 29/09/2004, 11h39
  4. Créer un graphique en GIF sous DELPHI pour du web
    Par Thom@s dans le forum Web & réseau
    Réponses: 20
    Dernier message: 08/07/2004, 15h40
  5. equivalent SELECT DISTINCT pour MyBase?
    Par chrisou31 dans le forum Bases de données
    Réponses: 2
    Dernier message: 08/03/2004, 19h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo