Oracle
 sql >> Base de données >  >> RDS >> Oracle

où rownum=1 requête prenant du temps dans Oracle

Cette question a déjà été répondue, je vais juste expliquer pourquoi parfois un filtre ROWNUM=1 ou ROWNUM <=1 peut entraîner un temps de réponse long.

Lorsqu'il rencontre un filtre ROWNUM (sur une seule table), l'optimiseur produit un FULL SCAN avec COUNT STOPKEY. Cela signifie qu'Oracle commencera à lire les lignes jusqu'à ce qu'il rencontre les N premières lignes (ici N=1). Une analyse complète lit les blocs depuis la première étendue jusqu'à la ligne des hautes eaux. Oracle n'a aucun moyen de déterminer quels blocs contiennent des lignes et lesquels n'en contiennent pas au préalable, tous les blocs seront donc lus jusqu'à ce que N lignes soient trouvées. Si les premiers blocs sont vides, cela peut entraîner de nombreuses lectures.

Considérez ce qui suit :

SQL> /* rows will take a lot of space because of the CHAR column */
SQL> create table example (id number, fill char(2000));

Table created

SQL> insert into example 
  2     select rownum, 'x' from all_objects where rownum <= 100000;

100000 rows inserted

SQL> commit;

Commit complete

SQL> delete from example where id <= 99000;

99000 rows deleted

SQL> set timing on
SQL> set autotrace traceonly
SQL> select * from example where rownum = 1;

Elapsed: 00:00:05.01

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=7 Card=1 Bytes=2015)    
   1    0   COUNT (STOPKEY)
   2    1     TABLE ACCESS (FULL) OF 'EXAMPLE' (TABLE) (Cost=7 Card=1588 [..])

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
      33211  consistent gets
      25901  physical reads
          0  redo size
       2237  bytes sent via SQL*Net to client
        278  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

Comme vous pouvez le constater, le nombre d'obtentions cohérentes est extrêmement élevé (pour une seule ligne). Cette situation peut se rencontrer dans certains cas où par exemple, vous insérez des lignes avec le /*+APPEND*/ indice (donc au-dessus de la ligne des hautes eaux), et vous supprimez également périodiquement les lignes les plus anciennes, ce qui laisse beaucoup d'espace vide au début du segment.