Este é o terceiro post de uma sequência que aborda os limites do MySQL em determinadas circunstâncias ( como pode ser visto no post 1 e 2). Nesta postagem abordaremos a temática das sub-consultas , que em alguns casos são executadas de fora para dentro ao invés de serem realizadas de fora para dentro como os usuários esperam.

É fácil pegar em subconsultas no MySQL, então eu vou tentar ser gentil. A consulta a seguir irá surpreender desagradavelmente usuários:

select * from a where a.id in (select id from b);


É relativamente simples aplicar as sub-consultas no MySQL, a consulta a seguir irá surpreender de forma negativa os usuários. Usuários esperam a consulta interna a ser executado primeiro, então os resultados a serem substituídos na IN () lista. Mas o que acontece ao contrário, é geralmente uma varredura completa ou verificação de índice de uma tabela, seguido por N consultas à tabela b. Isto é porque MySQL reescreve a consulta para fazer a consulta interna dependente da consulta externa, o que poderia ser uma otimização em alguns casos, mas desotimiza a consulta em muitos outros casos. NOT IN (SELECT ...) consultas executar mal, também.
(Nota: colocar uma lista literal de itens da IN () executa cláusula de multa É apenas quando há um SELECT dentro dele que ele funciona mal..)

Os usuários esperam a consulta interna ser executada primeiro, assim os resultados que serão substituídos na IN () lista. Mas acontece o contrário, geralmente uma varredura completa ou uma verificação de índice de uma tabela, seguido de N consultas à tabela b.

Isto ocorre por que o MySQL reescreve a consulta para poder realizar a consulta interna de forma dependente da consulta externa, o que poderia ser considerado uma otimização em casos específicos, mas diminui esta otimização na maioria dos casos.

NoT IN (SELECT....) também costuma executar de uma forma um pouco negativa as consultas. Colocando uma lista lateral na IN () executando uma cláusula de multa executando quando existe um SELECT dentro dele que funcione mal. A correção para este problema esta em andamento a alguns anos, e um dos engajados nos trabalhos de melhora é o Sergey Petrunia. Mas não está muito claro que o código oferece uma solução completa. Não tem sido mostrado nem um release GA ou RC, por isso não tem grande utilização.

Para ser justo, muitos servidores de banco de dados também têm desempenho sub-consultas muito pobres, isso já deveria ter sido corrigido. E muitos usuários MySQL aprenderam a escrever simplesmente JOINs, por isso gera uma série de limitações.