J'essaye de déterminer la meilleure approche générale pour interroger contre deux tables jointes qui ont beaucoup de données, où chaque table a une colonne dans la clause where. Imaginez un simple schéma w/deux tables:Dans MySQL, comment JOINmer deux très grandes tables qui ont toutes deux des colonnes dans la condition WHERE?
posts
id (int)
blog_id (int)
published_date (datetime)
title (varchar)
body (text)
posts_tags
post_id (int)
tag_id (int)
Avec les indices suivants:
posts: [blog_id, published_date]
tags: [tag_id, post_id]
Nous voulons sélectionner les 10 derniers messages sur un blog donné qui ont été marqués par "foo". Pour le bien de cette discussion, supposons que le blog a 10 millions de messages, et 1 million d'entre eux ont été marqués avec "foo". Quel est le moyen le plus efficace pour interroger ces données?
L'approche naïve serait de le faire:
SELECT
id, blog_id, published_date, title, body
FROM
posts p
INNER JOIN
posts_tags pt
ON pt.post_id = p.id
WHERE
p.blog_id = 1
AND pt.tag_id = 1
ORDER BY
p.published_date DESC
LIMIT 10
MySQL utilisera nos index, mais encore jusqu'à la fin numériser des millions d'enregistrements. Existe-t-il un moyen plus efficace de récupérer ces données sans dénormaliser le schéma?
Laissez le moteur faire le travail. Fournissez les astuces (index) et consultez le plan d'exécution. Si une analyse complète est effectuée, elle est soit requise (pour les indices donnés - vérifiez vos index de recouvrement), soit le générateur de plan échoue (peut-être pense-t-il qu'un balayage [complet] gagne toujours, auquel cas il peut même être correct). Je ne suis pas un administrateur de bases de données, mais je n'ai jamais été confronté à la nécessité de baser des données dénormalisées (les données dénormalisées transitoires ne sont pas identiques à un schéma relationnel dénormalisé [brisé]). –
Bonne question. La seule solution que j'ai trouvée à ce type de problème est la dénormalisation. – nathan