Voici une question que j'ai posée hier - https://stackoverflow.com/questions/22180727/left-joining-two-views-is-slow .
J'ai une bonne réponse qui m'a aidé mais je ne comprends pas pourquoi la jointure gauche est tellement plus lente que la recherche. L'accocation de gauche était de 16 secondes - et je suis à peu près sûr que mes tables sont d'au moins 90% optimisées - et lorsque vous faites la recherche, il suffit de .14 secondes. Quand j'ai laissé des tables de jointure, ce n'est pas si lent alors pourquoi vues?
Selon la MySQL Documentation sur Vues
Vues (y compris les vues mises à jour) sont disponibles dans MySQL Server 5.6. Les vues sont des requêtes stockées lorsqu'ils sont invoqués produisent un ensemble de résultats. Une vue agit comme une table virtuelle.
La première chose qui doit être réalisée à propos d'une vue est qu'elle produit un ensemble de résultats. Le jeu de résultats émergeant de la requête invoquée à partir de la vue est une table virtuelle car elle est créée à la demande. Il n'y a pas de DDL que vous pouvez invoquer ensuite pour indexer immédiatement le jeu de résultats. À toutes fins utiles, le jeu de résultats est une table sans index. En effet, la jointure gauche que vous exécutions est essentiellement un produit cartésien avec un peu de filtrage.
Pour vous donner un regard plus granulaire sur la jointure de deux points de vue, je vous référerai à un poste que j'ai fait l'année dernière expliquant les mécanismes internes MySQL utilise pour évaluer les jointures et la suivante ( y a-t-il une différence d'exécution entre une condition de jointure et un endroit où condition ? ). Je vais vous montrer le mécanisme tel que publié dans Comprendre MySQL Internals (page 172):
ORDER BY
et GROUP BY
.OK, il semble que des index soient utilisés. Cependant, regarde plus près. Si vous remplacez le mot View
pour Table
, regardez ce qui arrive à l'exécution du mécanisme:
views
et choisissez le meilleur pour chaque view
.view
, décidez si un view
Scan est mieux que lire sur une clé. S'il y a beaucoup d'enregistrements correspondant à la valeur de la clé, les avantages de la clé sont réduits et le view
Scan devient plus rapide.views
doit être jointe lorsque plusieurs views
est présent dans la requête.views
de la jointure.ORDER BY
et GROUP BY
.Chaque table (vue) n'a aucun index. Ainsi, travailler avec des tables virtuelles, des tables temporaires ou des tables sans index ne devient vraiment indistincte lors d'une jointure. Les clés utilisées ne sont que pour les opérations de jointure, pas tant pour la recherche de choses plus rapidement.
Pensez à Votre requête En choisissant deux livres téléphoniques, les pages jaunes de 2014 et les pages jaunes de 2013. Chaque livre de pages jaunes contient les pages blanches pour les numéros de téléphone résidentiels.
De toute évidence, il y a des différences entre les deux livres téléphoniques. Faire une participation de tables de base de données pour déterminer les différences entre 2013 et 2014 ne devrait poser aucun problème.
Imaginez la fusion des deux livres téléphoniques à la main pour localiser les différences. Cela semble fou, n'est-ce pas? Nonobstant, c'est exactement ce que vous demandez à MySQLD de faire lorsque vous vous joignez à deux points de vue. N'oubliez pas que vous ne rejoignez pas de vraies tables et il n'y a pas d'index à piggyback.
Maintenant, regardons en arrière la requête.
SELECT DISTINCT
viewA.TRID,
viewA.hits,
viewA.department,
viewA.admin,
viewA.publisher,
viewA.employee,
viewA.logincount,
viewA.registrationdate,
viewA.firstlogin,
viewA.lastlogin,
viewA.`month`,
viewA.`year`,
viewA.businesscategory,
viewA.mail,
viewA.givenname,
viewA.sn,
viewA.departmentnumber,
viewA.sa_title,
viewA.title,
viewA.supemail,
viewA.regionname
FROM
viewA
LEFT JOIN viewB ON viewA.TRID = viewB.TRID
WHERE viewB.TRID IS NULL
Vous utilisez une table virtuelle (table sans index), Viewa, y rejoignant une autre table virtuelle, Viewb. La table temporaire étant générée par intermittence serait aussi grande que la vie. Ensuite, vous exécutez un tri interne sur la grande table Temp pour le rendre distinct.
Compte tenu des mécanismes internes d'évaluation des joints, le long de la nature transitoire et sans index de l'ensemble de résultats d'une vue, votre requête d'origine (jointure de gauche de deux vues) devrait devenir des heures d'exécution des ordres de grandeur. Dans le même temps, le Réponse que vous avez obtenu de Stackoverflow devrait bien fonctionner, étant donné le même algorithme de jointure que je viens de décrire.
J'espère que les détails de Gory, je viens de poster des réponses de votre question sur la raison.