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

Sob quais condições ROWNUM=1 aumenta significativamente o desempenho em uma consulta de estilo existente


Ele melhora significativamente o desempenho (dezenas de porcentagem média) em consultas que não podem ser resolvidas por simples pesquisa de índice único, por exemplo A tabela une. No entanto, tem o potencial de ocultar erros de dados/aplicativos.

Vamos a uma tabela:
create table t (id number(10,0), padding varchar2(1000));  

--intencionalmente não use PK para tornar o exemplo o mais simples possível. O preenchimento é usado para simular a carga de dados real em cada registro

com muitos registros:
insert into t (id, padding)
select rownum, rpad(' ', 1000) from dual connect by level < 10000

Agora, se você perguntar algo como
select 1 into ll_exists
from t where id = 5;

o banco de dados deve percorrer toda a tabela se encontrou o único registro correspondente no primeiro bloco de dados (o que, aliás, não podemos saber porque poderia ser inserido de muitas maneiras diferentes) ou no último. Isso porque ele não sabe que existe apenas um registro correspondente. Por outro lado, se você usar ... e rownum =1, ele pode parar de percorrer os dados após o registro ser encontrado porque você disse que não há (ou não é necessário) outro registro correspondente.

A desvantagem é que com a restrição rownum você pode obter resultados não determinísticos se os dados contiverem mais de um registro possível.
select id into ll_id
from t where mod (id, 2) = 1
and rownum = 1;

então eu posso receber do DB resposta 1, bem como 3, bem como 123 ... a ordem não é garantida e essa é a consequência. (sem a cláusula rownum eu receberia uma exceção TOO_MANY_ROWS. Depende da situação qual é a pior)

Se você realmente deseja consultar o que testa a existência, ESCREVA ASSIM.
begin

select 'It does' 
  into ls_exists
from dual where
exists (your_original_query_without_rownum);

do_something_when_it_does_exist
exception
  when no_data_found then
    do_something_when_it_doesn't_exist
end;