Je veux comprendre ce qui suit.
Supposons que j'ai une requête compliquée avec disons une jointure de 5 tables par groupe par sommations et par ordre.
Abstraction faite de toutes les optimisations à la requête elle - même , par exemple des index , etc.
Y at - il avantage de performance significative en utilisant LIMIT
? Je suppose que toutes les requêtes (et les résultats) doivent être traitées avant d' appliquer LIMIT, donc l'utilisation d'un LIMIT pour récupérer un sous-ensemble des résultats, cela offre-t-il une amélioration significative / perceptible?
11
LIMIT
améliorent l'efficacité: Optimisation des requêtes LIMITRéponses:
Si vous souhaitez profiter de
LIMIT
pour améliorer les performances, vous avez besoinLIMIT
avantJOIN
Ces principes peuvent aller très loin si vous pouvez les orchestrer.
J'ai appris ces concepts en regardant cette vidéo YouTube (écoutez attentivement à travers l'accent français)
J'ai utilisé ces concepts pour répondre à une question StackOverflow très difficile sur l'obtention des 40 meilleurs articles de certaines tables: 12 mai 2011: récupération d'une seule ligne à partir de la table de jointure .
Dans ma réponse à cette question (16 mai 2011) , j'ai écrit la requête suivante et l'ai soigneusement testée:
Veuillez noter la ligne dans la requête avec le
LIMIT
Cette sous-requête est enfouie à trois niveaux de profondeur. Cela m'a permis d'utiliser les 40 derniers articles
LIMIT
. Ensuite, j'ai effectué les JOIN nécessaires par la suite.LEÇONS APPRISES
LIMIT
sous-requêtes internes peut ne pas toujours être la réponse en raison de la cardinalité des index, du contenu des données et de la taille du jeu de résultats à partir duLIMIT
. Si vous avez tous vos «canards d'affilée» (ayez les quatre principes à l'esprit pour votre requête), vous pouvez obtenir des résultats étonnamment bons.LIMIT
en rassemblant uniquement les clés.la source
(A [LEFT] JOIN B) LIMIT 100
Est donc équivalent à(A LIMIT 100) [LEFT] JOIN (B LIMIT 100)
? Où[LEFT] JOIN
signifie jointure externe ou interne(A LIMIT 100) [LEFT] JOIN B
. L'idée est d'utiliserLIMIT
pour déterminer la taille de l'ensemble de résultats le plus tôt possible. J'utilise égalementLEFT JOIN
au lieu deINNER JOIN
carLEFT JOIN
préservera l'ordre des touches sur le côté gauche.(A LEFT JOIN B) GROUP BY A.pk LIMIT 100
peuvent généralement être réécrits comme(A LIMIT 100) LEFT JOIN B GROUP BY A.pk
(pas de jointure interne ici, avec des jointures internes, ils ne seraient pas équivalents.) L'exemple de Rolando est exactement un tel cas.Lorsqu'une requête est exécutée, elle est d'abord traduite en un plan composé de plusieurs opérateurs. Il existe deux types d'opérateurs de base: bloquant et non bloquant. Un opérateur non bloquant récupère une ligne (ou quelques lignes) de son ou ses enfants pour chaque ligne demandée. Un opérateur de blocage, d'autre part, doit lire et traiter l'ensemble de lignes de tous ses enfants avant de pouvoir produire une sortie.
Le tri est un opérateur de blocage typique. Ainsi, une sélection avec commande par ne bénéficie pas beaucoup d'une limite. Cependant, il existe des SGBDR qui peuvent utiliser un algorithme de tri qui nécessite moins de mémoire et est plus rapide lorsqu'une clause limite est fournie. Dans ce cas, il suffit de stocker les n premières lignes actuellement et de les retirer de la mémoire au fur et à mesure que les lignes précédentes se présentent. Cela peut être un gain de performances significatif. Cependant, je ne suis pas sûr à 100% que MySQL ait cette capacité.
Quoi qu'il en soit, même un tri par limite doit toujours traiter l'ensemble de lignes d'entrée avant de pouvoir produire la première ligne de sortie. Bien que cet algorithme, s'il est implémenté, puisse accélérer le tri, si le reste de la requête est la partie la plus coûteuse, le temps d'exécution total ne s'améliorera pas de manière significative en raison d'une limite fournie.
la source
GROUP BY
pourrait potentiellement conduire à un plan qui ne contient pas d'opérateurs de blocage.Dans mon cas, je peux dire Oui , même si je ne comprends toujours pas pourquoi.
Notez le temps: 18 secondes. Même demande avec une grosse LIMITE:
Plus de dix fois plus rapide !!!
EXPLAIN donne le même résultat pour les deux requêtes.
LIMIT ne devrait interférer que pour limiter le jeu de résultats (c'est-à-dire que si je fais un LIMIT 4, je n'ai que les 4 premières lignes du jeu de résultats ci-dessus).
la source
LIMIT
. Votre première requête s'exécute en 18 secondes, donnant un ensemble de résultats. Toutes les données de la 2e requête sont déjà mises en cache dans le pool de mémoire tampon InnoDB en raison de la première requête, donc bien sûr la 2e requête doit être plus rapide, même si vous redémarrez mysql, exécutez la 1ère requête, redémarrez mysql et exécutez la 2e requête, vous obtiendrez le même résultat. . Avoir un meilleur résultat pourLIMIT
ne peut venir que de faire: 1)LIMIT
avantJOIN
, 2) LIMIT dans l'ordre de triASC
ouDESC
.