sql >> Base de Datos >  >> RDS >> Oracle

donde rownum=1 consulta tomando tiempo en Oracle

Esta pregunta ya ha sido respondida, solo proporcionaré una explicación de por qué a veces un filtro ROWNUM=1 o ROWNUM <=1 puede resultar en un tiempo de respuesta prolongado.

Al encontrar un filtro ROWNUM (en una sola tabla), el optimizador producirá un ESCANEO COMPLETO con COUNT STOPKEY. Esto significa que Oracle comenzará a leer filas hasta que encuentre las primeras N filas (aquí N=1). Un análisis completo lee bloques desde la primera extensión hasta la marca de límite superior. Oracle no tiene forma de determinar qué bloques contienen filas y cuáles no, por lo tanto, todos los bloques se leerán hasta que se encuentren N filas. Si los primeros bloques están vacíos, podría resultar en muchas lecturas.

Considere lo siguiente:

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

Como puede ver, la cantidad de resultados consistentes es extremadamente alta (para una sola fila). Esta situación podría encontrarse en algunos casos en los que, por ejemplo, inserta filas con /*+APPEND*/ sugerencia (por lo tanto, por encima de la marca de agua alta), y también elimina las filas más antiguas periódicamente, lo que da como resultado una gran cantidad de espacio vacío al comienzo del segmento.