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

Quais são as implicações de desempenho da cláusula Oracle IN sem junções?


Se as estatísticas em sua tabela forem precisas, é muito improvável que o otimizador opte por fazer uma verificação de tabela em vez de usar o índice de chave primária quando você tem apenas 1.000 elementos codificados em WHERE cláusula. A melhor abordagem seria reunir (ou definir) estatísticas precisas sobre seus objetos, pois isso deve fazer com que coisas boas aconteçam automaticamente, em vez de tentar fazer muita ginástica para contornar estatísticas incorretas.

Se presumirmos que as estatísticas são imprecisas a ponto de o otimizador acreditar que uma verificação de tabela seria mais eficiente do que usar o índice de chave primária, você poderia adicionar um DYNAMIC_SAMPLING dica que forçaria o otimizador a coletar estatísticas mais precisas antes de otimizar a instrução ou um CARDINALITY dica para substituir a estimativa de cardinalidade padrão do otimizador. Nenhum deles exigiria saber nada sobre os índices disponíveis, exigiria apenas conhecer o alias da tabela (ou nome, se não houver alias). DYNAMIC_SAMPLING seria a abordagem mais segura e robusta, mas aumentaria o tempo da etapa de análise.

Se você estiver criando uma instrução SQL com um número variável de parâmetros codificados em um IN cláusula, você provavelmente criará problemas de desempenho para si mesmo inundando seu pool compartilhado com SQL não compartilhável e forçando o banco de dados a gastar muito tempo analisando cada variante separadamente. Seria muito mais eficiente se você criasse uma única instrução SQL compartilhável que pudesse ser analisada uma vez. Dependendo de onde seu IN os valores das cláusulas estão vindo, isso pode ser algo como
SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM global_temporary_table);

ou
SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM TABLE( nested_table ));

ou
SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM some_other_source);

Se você se resumisse a uma única instrução SQL compartilhável, além de evitar o custo de reanalisar constantemente a instrução, você teria várias opções para forçar um plano específico que não envolve a modificação da instrução SQL. Diferentes versões do Oracle têm diferentes opções para estabilidade do plano -- existem delineamentos armazenados , Gerenciamento de plano SQL e perfis SQL entre outras tecnologias dependendo do seu lançamento. Você pode usá-los para forçar planos específicos para instruções SQL específicas. No entanto, se você continuar gerando novas instruções SQL que precisam ser analisadas novamente, fica muito difícil usar essas tecnologias.