Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

onde rownum=1 consulta demorando no Oracle


Esta pergunta já foi respondida, vou apenas explicar porque às vezes um filtro ROWNUM=1 ou ROWNUM <=1 pode resultar em um longo tempo de resposta.

Ao encontrar um filtro ROWNUM (em uma única tabela), o otimizador produzirá um FULL SCAN com COUNT STOPKEY. Isso significa que o Oracle começará a ler as linhas até encontrar as primeiras N linhas (aqui N=1). Uma varredura completa lê blocos da primeira extensão até a marca d'água alta. O Oracle não tem como determinar quais blocos contêm linhas e quais não contêm, todos os blocos serão lidos até que N linhas sejam encontradas. Se os primeiros blocos estiverem vazios, isso poderá resultar em muitas leituras.

Considere o seguinte:
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 você pode ver, o número de obtenções consistentes é extremamente alto (para uma única linha). Essa situação pode ser encontrada em alguns casos em que, por exemplo, você insere linhas com o /*+APPEND*/ dica (portanto, acima da marca d'água alta), e você também exclui as linhas mais antigas periodicamente, resultando em muito espaço vazio no início do segmento.