Eu quero entender o seguinte.
Suponha que eu tenha uma consulta complicada com, digamos, uma junção de 5 tabelas por grupo por somatórios e por ordem.
Deixando de lado quaisquer otimizações para a própria consulta, por exemplo, índices etc.
Existe algum benefício significativo de desempenho usando LIMIT
? Suponho que toda a consulta (e resultados) deve ser processada antes da aplicação de LIMIT; portanto, usando um LIMIT para recuperar um subconjunto dos resultados, isso oferece alguma melhoria significativa / perceptível?
mysql
performance
join
Jim
fonte
fonte
LIMIT
melhora a eficiência: Otimizando LIMIT ConsultasRespostas:
Se você deseja aproveitar
LIMIT
para melhorar o desempenho, precisaLIMIT
antesJOIN
Esses princípios podem percorrer um longo caminho se você puder orquestrá-los.
Aprendi esses conceitos assistindo a este vídeo do YouTube (ouça com atenção o sotaque francês)
Usei esses conceitos para responder a uma pergunta muito difícil do StackOverflow sobre como obter os 40 principais artigos de algumas tabelas: 12 de maio de 2011: Buscando uma única linha da tabela de junção .
Na minha resposta a essa pergunta (16 de maio de 2011) , escrevi a seguinte consulta e a testei completamente:
Observe a linha na consulta com o
LIMIT
Esta subconsulta está enterrada a três níveis de profundidade. Isso me permitiu obter os últimos 40 artigos usando
LIMIT
. Depois, executei os JOINs necessários depois.LIÇÕES APRENDIDAS
LIMIT
subconsultas internas nem sempre pode ser a resposta devido à cardinalidade dos índices, ao conteúdo dos dados e ao tamanho do conjunto de resultados doLIMIT
. Se você tiver todos os seus "patos consecutivos" (tenha os quatro princípios em mente para sua consulta), poderá obter resultados surpreendentemente bons.LIMIT
coletar apenas as chaves.fonte
(A [LEFT] JOIN B) LIMIT 100
é equivalente a(A LIMIT 100) [LEFT] JOIN (B LIMIT 100)
? Onde[LEFT] JOIN
meios exteriores ou interiores juntar(A LIMIT 100) [LEFT] JOIN B
. A idéia é usarLIMIT
para determinar o tamanho do conjunto de resultados o mais cedo possível. Eu também uso emLEFT JOIN
vez deINNER JOIN
porqueLEFT JOIN
preservará a ordem das teclas no lado esquerdo.(A LEFT JOIN B) GROUP BY A.pk LIMIT 100
geralmente podem ser reescritas como(A LIMIT 100) LEFT JOIN B GROUP BY A.pk
(não há INNER JOIN aqui, com junções internas elas não seriam equivalentes.) O exemplo de Rolando é exatamente esse caso.Quando uma consulta é executada, ela é traduzida primeiro em um plano composto por vários operadores. Existem dois tipos básicos de operadores: bloqueio e não bloqueio. Um Operador sem bloqueio recupera uma linha (ou algumas linhas) de seu filho ou filhos para cada linha solicitada a ele. Um Operador de Bloqueio, por outro lado, precisa ler e processar todo o conjunto de linhas de todos os seus filhos antes de poder produzir qualquer saída.
A classificação é um operador de bloqueio típico. Portanto, um select com order by não se beneficia muito de um limite. No entanto, existem RDBMSs que podem utilizar um algoritmo de classificação que precisa de menos memória e é mais rápido quando uma cláusula de limite é fornecida. Nesse caso, basta armazenar as primeiras n linhas atualmente e removê-las da memória à medida que as linhas anteriores aparecem. Isso pode ser um ganho significativo de desempenho. No entanto, não tenho 100% de certeza de que o MySQL tenha essa capacidade.
De qualquer forma, mesmo uma classificação de limite ainda precisa processar toda a linha de entrada definida antes de poder produzir a primeira linha de saída. Embora esse algoritmo, se implementado, possa acelerar a classificação, se o restante da consulta for a parte mais cara, o tempo total de execução não melhorará significativamente devido a um limite fornecido.
fonte
GROUP BY
pode levar a um plano que não contenha operadores de bloqueio.No meu caso, posso dizer sim , mesmo que eu (ainda) não entenda o porquê.
Observe o tempo: 18 segundos. Mesmo pedido com um grande LIMIT:
Mais de dez vezes mais rápido !!!
EXPLAIN fornece o mesmo resultado para os dois pedidos.
LIMIT deve interferir apenas para limitar o conjunto de resultados (ou seja, se eu fizer um LIMIT 4, obtive apenas as 4 primeiras linhas do conjunto de resultados acima).
fonte
LIMIT
. Sua primeira consulta é executada em 18 segundos, fornecendo um conjunto de resultados. Todos os dados da 2ª consulta já estão armazenados em cache no buffer pool do InnoDB devido à primeira consulta. Portanto, a 2ª consulta deve ser mais rápida. Mesmo se você reiniciar o mysql, execute a 1ª consulta, reinicie o mysql e execute a 2ª consulta. consulta, você obterá o mesmo resultado. . Ter um resultado melhor paraLIMIT
somente pode resultar de: 1)LIMIT
antesJOIN
, 2) LIMIT na ordem de classificaçãoASC
ouDESC
.