Query Optimizer VS Foreign Keys
Pessoal, depois da WebCast que fiz falando sobre o Query Optimizer, quero compartilhar um caso onde na minha opinião ele infelizmente não foi tão esperto assim 😦
Por sinal o vídeo já esta disponível para download…. é só acessar o link de cadastro para a webcast e baixar…
Veja bem, no meu banco de dados tenho 2 tabelas assim…
CONCC030 – Tabela de propostas, e CONCC036 tabela que relaciona uma proposta com uma Cota.
As chaves das duas tabelas são, ID_Empresa, ID_Documento, ID_Tipo_Documento. Na tabela CONCC036 eu tenho uma foreign key forçando a integridade entre as tabelas. A foreign key é formada pelas 3 colunas que acabei de mencionar.
Tenho uma consulta assim:
SELECT ID_Bem
FROM CONCC030
INNER JOIN CONCC036
ON CONCC036.ID_Tipo_Documento = CONCC030.ID_Tipo_Documento
AND CONCC036.ID_Documento = CONCC030.ID_Documento
WHERE CONCC036.ID_Empresa = 1
AND CONCC036.ID_Cota = 123456
Bom, como podemos observar, o join não esta sendo feito pelas 3 colunas da foreign key… esta faltando especificar a coluna ID_Empresa, porém ela esta no WHERE, fazendo um filtro por ID_Empresa = 1.
O que podemos concluir com isso, ora, o QO sabe que existe uma foreign key entre as tabelas e sabe quais são as colunas da FK, porque então não utilizar o filtro da tabela CONCC036.ID_Empresa = 1 (WHERE) e também aplicar este filtro na CONCC030.ID_Empresa ?
Com certeza o desenvolvedor que escreveu esta consulta não especificou o ID_Empresa no join justamente porque ele sabia que a coluna seria utilizada no where. Mas isso causou um problema para o QO, pois ele não conseguiu utilizar um índice que temos para fazer o link entre as duas tabelas, já que o índice esta ordenado justamente pela ordem, ID_Empresa, ID_Documento, ID_Tipo_Documento….
O QO poderia muito bem aplicar o filtro em CONCC030.ID_Empresa = 1 e utilizar as outras colunas no join para fazer o filtro…
Outra coisa triste, a funcionalidade que mencionei na WebCast sobre ele descartar as tabelas caso a existência de uma foreign key, só funciona para foreign Keys ligadas por apenas uma coluna… ou seja, se você tiver uma foreign key que liga uma tabela por mais de uma coluna e tentar utilizar a funcionalidade que mencionei, não vai conseguir…
Bom, fica a seguinte dica, ao escrever uma consulta, SEMPRE(does not matter what!) especifique todas as colunas no seu join…
Abraço…