Por favor, antes de sinalizar como duplicado, leia os últimos parágrafos.
Em um banco de dados Oracle 9i, essa consulta é executada em 0,18 segundos :
select
count(*)
from
dba_synonyms s,dba_objects t
where
s.TABLE_OWNER = t.OWNER(+) and
s.TABLE_NAME = t.OBJECT_NAME(+) and
s.DB_LINK is null and
t.OWNER is null;
...mas este é executado em terríveis 120 segundos !:
select
count(*)
from
dba_synonyms s left join dba_objects t
on ( s.TABLE_OWNER = t.OWNER and s.TABLE_NAME = t.OBJECT_NAME )
where
s.DB_LINK is null and
t.OWNER is null
Observe que a única diferença é usar a sintaxe de junção proprietária do Oracle versus a sintaxe de junção ANSI.
Esta questão não é uma duplicata desta porque aquela outra questão é sobre uma consulta muito complexa envolvendo mais de 9 tabelas, e a única resposta aponta que as consultas são muito diferentes além do uso da sintaxe (principalmente a ordem das tabelas).
No meu caso é uma consulta extremamente simples, uma mera junção entre duas relações sem maiores complicações de diferenças, inclusive a ordem das tabelas.
- Isso é um bug no Oracle 9i?
- Qual é a causa de uma diferença tão dramática no desempenho?
Bem, depois de muito tempo sem respostas. Já fiz alguns testes.
Fiz a mesma consulta em 10g e 11g e ambas as versões, aquela com junções ANSI e as com junções WHERE rodam em menos de 1 segundo.
Como os problemas existem apenas no 9i, a mesma versão em que o suporte para ANSI se junta foi introduzido, presumo que seja um bug no 9i que poderia ou não ter sido resolvido em um patch.
Felizmente, como mencionei, a partir de 10g, ambos os tipos de junções funcionam bem.