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

Oracle usa ou ignora coluna indexada dependendo do formato de to_date(literal)


Ok - vou tentar, isso é principalmente dedução das informações disponíveis:

Por que a Oracle escolhe um plano de execução diferente?

Parece que na sua segunda consulta com o formato de data incomum, o otimizador não tem ideia de qual é o valor da data resultante. Você vê o Predicado de filtro:

1 - filter(TO_DATE('20140610 ','yyyymmdd ')<=TO_DATE(' 2014-06-10 23:59:59', 'syyyy-mm-dd hh24:mi:ss'))

O que significa que o otimizador nem tem certeza de que a primeira data é menor que a segunda! Isso significa que o otimizador não tem ideia do número de linhas retornadas e usará apenas um plano genérico sem levar em consideração estatísticas específicas. Seria o mesmo se você tivesse uma função definida pelo usuário xyt() que retornaria uma data para o intervalo. O otimizador não tem como saber qual valor de data resultará - Isso significa que você obtém um plano geral para todos os fins, que deve ser bastante decente para qualquer intervalo de data especificado.

No primeiro e terceiro caso, o otimizador parece entender a data diretamente e pode adivinhar o número de linhas que estão no intervalo de datas usando estatísticas. Então, enquanto a segunda consulta foi para o otimizador como BETWEEN X AND 3 esta consulta é como BETWEEN 1 AND 3 Assim, ele otimiza o plano de consulta para o número previsto de linhas retornadas!

O estranho parece ser que o otimizador de consultas tem esses problemas com um formato de data estranho, pode ser arquivado como um bug/solicitação de melhoria ...

Mas um ponto importante:
  1. Uma varredura completa da tabela não precisa ser um plano RUIM... Assim como usar um índice nem sempre é mais rápido!
  2. O custo no plano de consulta não está diretamente relacionado ao tempo de execução ou desempenho real - é uma medida interna para comparar planos diferentes para a MESMA CONSULTA (portanto, você não pode comparar o custo de consultas diferentes, como suas consultas 1 ,2 e 3)

Basicamente, se você retornar um grande número de linhas de uma tabela, uma varredura completa da tabela sem acesso ao índice será, em muitos casos, muito mais rápida, especialmente ao operar em determinadas partições! - A verificação da tabela só acessará a permissão para o intervalo de datas correspondente - portanto, apenas para a data em questão e retornará todas as linhas desta partição. Isso é muito mais rápido do que consultar o índice para cada linha e extrair a linha pelo acesso ao índice ... Tente criar o perfil das consultas - a verificação completa da tabela na partição deve ser 3 vezes mais rápida com muito menos IO