Pergunta

Eu tenho uma consulta particularmente lento devido à grande quantidade de informação a ser unidas. No entanto eu precisava para adicionar uma cláusula WHERE na forma de id in (SELECT id da tabela).

Eu quero saber se existe algum ganho a partir do seguinte, e mais urgente, vai mesmo dar os resultados desejados.

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

como uma alternativa para:

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

Update: MySQL não pode ser mais específico pena Tabela A é efetivamente uma junção entre 7 mesas diferentes. uso de * é para exemplos

Editar, b não selecionado

Foi útil?

Solução

A sua pergunta foi sobre a diferença entre estes dois:

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

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

O primeiro é uma correlacionada subconsulta. Isso pode causar MySQL para executar a subconsulta para cada linha de a.

O último é uma não-correlacionada subconsulta. MySQL deve ser capaz de executá-lo uma vez e armazenar em cache os resultados para comparação com cada linha de a.

Gostaria de usar o último.

Outras dicas

Ambas as consultas que você lista são o equivalente a:

select a.* 
from a 
inner join b on b.id = a.id

Quase todos os otimizadores vai executá-las da mesma forma.

Você pode postar um plano de execução real, e alguém aqui pode dar-lhe uma maneira de acelerá-lo. Ela ajuda se você especificar o servidor de banco de dados você está usando.

YMMV, mas eu tenho encontrado frequentemente usando EXISTS em vez de faz consultas correr mais rápido.

SELECT a.* FROM a WHERE EXISTS (SELECT 1 FROM b WHERE b.id = a.id)

É claro que, sem ver o resto da consulta e do contexto, isso pode não fazer a consulta mais rápido.

junção pode ser uma opção mais preferível, mas se aparece a.id mais de uma vez na coluna ID de b, você teria que jogar um distinto lá, e você mais do que provável ir para trás em termos de otimização.

Eu nunca usaria uma subconsulta como esta. A juntar-se seria muito mais rápido.

select a.*
from a 
join b on a.id = b.id

É claro que não usar select * ou (especialmente nunca usá-lo ao fazer uma junção de pelo menos um campo é repetido) e desperdiça recursos de rede para enviar dados unnneeded.

Você já olhou para o plano de execução?

Como cerca

select a.* 
from a 
inner join b
on a.id = b.id

presumivelmente os campos de identificação são as chaves primárias?

Select a.* from a
inner join (Select distinct id from b) c
on a.ID = c.AssetID

Eu tentei todas as 3 versões e eles correram sobre o mesmo. O plano de execução foi a mesma (junção interna, IN (com e sem cláusula WHERE na subconsulta), existe)

Desde que você não está selecionando quaisquer outros campos de B, eu prefiro usar a IN (Select ...) ninguém para onde iria olhar para a consulta e saber o que você está tentando fazer (mostrar Somente em um caso em b. ).

Seu problema é mais provável nos sete tabelas dentro "a"

fazer a FROM tabela conter o "a.id" fazer o próximo juntar-se: junção interna b em a.id = b.id

, em seguida, juntar-se outros seis mesas.

Você realmente precisa mostrar toda a consulta, a lista de todos os índices, e contagens de linha aproximados de cada tabela se você quiser ajuda real

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top