Mysql
 sql >> Base de données >  >> RDS >> Mysql

Optimiser les requêtes MySQL avec des jointures lourdes

Vos données sont mal cluster .

InnoDB stockera les lignes avec des PK "proches" physiquement proches les unes des autres. Étant donné que vos tables enfants utilisent des PK de substitution, leurs lignes seront stockées de manière aléatoire. Lorsque vient le temps de faire des calculs pour la ligne donnée dans la table "maître", le SGBD doit sauter partout pour rassembler les lignes liées des tables enfants.

Au lieu de clés de substitution, essayez d'utiliser des clés plus "naturelles", avec le PK du parent dans le bord d'attaque, similaire à ceci :

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)

REMARQUE :Cela suppose que created La résolution de est assez fine et le rating_no a été ajouté pour permettre plusieurs évaluations par entry_id . Ce n'est qu'un exemple - vous pouvez varier les PK selon vos besoins.

Cela "forcera" les lignes appartenant au même entry_id à stocker physiquement proches les uns des autres, de sorte qu'un SUM ou AVG peut être calculé par un simple balayage de plage sur la clé PK/clustering et avec très peu d'E/S.

Sinon (par exemple, si vous utilisez MyISAM qui ne prend pas en charge le clustering), couvrir la requête avec des index afin que les tables enfants ne soient pas du tout touchées lors de la requête.

En plus de cela, vous pouvez dénormaliser votre conception et mettre en cache les résultats actuels dans la table parent :

  • Stockez SUM(score_adjustments.amount) en tant que champ physique et ajustez-le via des déclencheurs chaque fois qu'une ligne est insérée, mise à jour ou supprimée de score_adjustments .
  • Stocker SUM(rating_adjustments.rating) comme "S" et COUNT(rating_adjustments.rating) comme "C". Lorsqu'une ligne est ajoutée à rating_adjustments , ajoutez-le à S et incrémentez C. Calculez S/C au moment de l'exécution pour obtenir la moyenne. Gérez les mises à jour et les suppressions de la même manière.