Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Otimizando consultas MySQL com junções pesadas


Seus dados estão mal cluster .

O InnoDB armazenará linhas com PKs "próximos" fisicamente próximos. Como suas tabelas filhas usam PKs substitutos, suas linhas serão armazenadas aleatoriamente. Quando chega a hora de fazer cálculos para uma determinada linha na tabela "mestre", o DBMS deve pular em todos os lugares para reunir as linhas relacionadas das tabelas filhas.

Em vez de chaves substitutas, tente usar chaves mais "naturais", com o PK do pai na borda principal, semelhante a isto:
score_adjustments:
    entry_id: INT(11), FOREIGN KEY (entries.id)
    created: DATETIME
    amount: INT(4)
    PRIMARY KEY (entry_id, created)

rating_adjustments:
    entry_id: INT(11), FOREIGN KEY (entries.id)
    rating_no: INT(11)
    rating: DOUBLE
    PRIMARY KEY (entry_id, rating_no)

NOTA:Isso pressupõe created a resolução de é boa o suficiente e o rating_no foi adicionado para permitir várias classificações por entry_id . Este é apenas um exemplo - você pode variar os PKs de acordo com suas necessidades.

Isso "forçará" as linhas pertencentes ao mesmo entry_id sejam armazenados fisicamente próximos, de modo que um SUM ou AVG possa ser calculado por apenas uma varredura de intervalo na chave PK/clustering e com muito poucas E/Ss.

Como alternativa (por exemplo, se você estiver usando o MyISAM que não suporta clustering), cobrir a consulta com índices para que as tabelas filhas não sejam tocadas durante a consulta.

Além disso, você pode desnormalizar seu design e armazenar em cache os resultados atuais na tabela pai:
  • Armazene SUM(score_adjustments.amount) como um campo físico e ajuste-o por meio de acionadores sempre que uma linha for inserida, atualizada ou excluída de score_adjustments .
  • Armazenar SUM(rating_adjustments.rating) como "S" e COUNT(rating_adjustments.rating) como "C". Quando uma linha é adicionada a rating_adjustments , adicione-o a S e incremente C. Calcule S/C em tempo de execução para obter a média. Lide com atualizações e exclusões de maneira semelhante.