Pourquoi la requête suivante copie-t-elle les données de table?
-
10-10-2019 - |
Question
SELECT COUNT(*) AS cnt
FROM products
WHERE ExternalProductId IS NOT NULL
GROUP BY SourceId, ExternalProductId
HAVING cnt > 1
Il y a un index sur (ExternalProductid, SourceId, Anotherfield). Un explication montre que l'index est utilisé. Ceci est imprimé dans la colonne "supplémentaire" d'expliquer:
Using where; Using index; Using temporary; Using filesort
Quand j'exécute la requête, je vois via Show ProcessList:
Copying to tmp table on disk
Puis-je modifier cette requête pour travailler en place sur l'index? Cela ne me dérange pas non plus si les résultats que j'obtiens sont légèrement inexacts en raison d'autres processus fonctionnant simultanément sur ce tableau - puis-je modifier le niveau d'isolement pour augmenter les performances de la requête?
La solution
Si vous inversez les colonnes de votre GROUP BY
Pour correspondre à la commande des deux premiers champs de votre index de composé, il utilisera votre index de composé beaucoup plus efficacement.
SELECT COUNT(*) AS cnt
FROM products
WHERE ExternalProductId IS NOT NULL
GROUP BY ExternalProductId, SourceId
HAVING cnt > 1
Votre plaine d'exécution de requête doit se transformer en 'Using where; Using index'
, et débarrassez-vous à la fois de la table temporaire et du port de fichiers causée par l'autre GROUP BY
.
Vous obtiendrez toujours les mêmes résultats, mais ce sera dans un ordre légèrement différent.
Autres conseils
Quelques choses à essayer:
MySQL triera automatiquement avec un groupe par. Si vous ne vous souciez pas de l'ordre de tri, ajoutez une clause «Order by Null». Cela éliminera le point de vente de fichiers et éventuellement le tableau temporaire.
Supprimez le nombre (*) et utilisez le nom d'une colonne dans l'index au lieu du wildcard.
Aussi. Quel est votre index? Pouvez-vous nous montrer l'instruction Create Table Full?