Executando 10.8.8-MariaDB-log
Tenho uma consulta muito complexa para um site de comparação.
Essencialmente
SELECT <columns> FROM <tables>
JOIN <derived table 1 for first comparison>
JOIN <derived table 2 for first comparison>
JOIN <derived table 1 for second comparison>
JOIN <derived table 2 for second comparison>
Funciona em <0,1s
Se eu mudar para
SELECT <columns> FROM <tables>
JOIN <derived table 1 for first comparison>
JOIN <derived table 2 for first comparison>
JOIN <derived table 1 for second comparison>
JOIN <derived table 2 for second comparison>
JOIN <derived table 1 for third comparison>
JOIN <derived table 2 for third comparison>
Demora mais de 10 segundos
Os índices são sólidos e o sql para criar as tabelas derivadas é o mesmo para cada comparação, exceto um valor de parâmetro de ID. Tudo o que muda é o número deles.
Eu suspeito que há algum buffer/cache que precisa ser aumentado um pouco? 🤷♂️
Sim , eu poderia reescrever a página/sql inteiramente para fazer isso por meio de um mecanismo muito diferente, mas se eu puder consertar isso com uma simples alteração de configuração, dados os recursos disponíveis na máquina, prefiro fazer isso. O tempo é curto.
Compreendo que isso possa ser um problema x/y, mas espero que haja um fruto fácil de alcançar que os mais experientes aqui sejam capazes de identificar imediatamente.
FWIW - filmando no escuro - tentei quadruplicar o tamanho desses três e não fez diferença:
join_buffer_size = 32M (to 128M)
sort_buffer_size = 4M (to 16M)
read_rnd_buffer_size = 4M (to 16M)
Obrigado
TIL sobre
STRAIGHT_JOIN
.STRAIGHT_JOIN
é comoJOIN
, exceto que diz ao otimizador de consulta para executar a consulta da maneira que você a criou.Por que isso é importante? Fatoriais, basicamente.
O otimizador conhece muitos truques inteligentes para adivinhar o melhor plano de execução, mas ESSENCIALMENTE, a complexidade de trabalhar esse plano de execução segue um padrão fatorial.
No exemplo da minha pergunta original, eu tinha 14 tabelas. 87 bilhões de opções
E então 16 mesas. 2 TRILHÕES de opções
Como eu disse, o otimizador não é tão burro, pode podar muito e usar muitos atalhos, mas acho que os números ilustram o problema com MUITAS tabelas em uma consulta. O problema não é quanto tempo a consulta leva para ser executada, mas sim quanto tempo o otimizador leva para descobrir COMO executá-la.
Caso em questão. Tenho uma consulta que estou testando/mexendo na minha frente agora, com 18 tabelas.
Eu não fiz literalmente nada , a não ser substituir todos os meus
JOIN
s porSTRAIGHT_JOIN
s.O resultado? Meu tempo de consulta caiu de 1,65s para 0,002s .
Essa construção é péssima para o desempenho porque nenhuma das "tabelas derivadas" possui índices:
Então, sim, adicionar mais
JOIN
é péssimo para o desempenho.Não, você não pode sair do problema. (O ajuste pode ajudar, mas não é uma solução real.)
Vamos ver um mais completo
SELECT
, junto com algunsSHOW CREATE TABLEs
; poderemos fornecer algumas sugestões construtivas.