J'ai un problème sérieux avec MySQL (innoDB) 5.0.Vérification de la plage Mysql au lieu de l'utilisation de l'index sur la jointure interne
Une requête SQL très simple est exécutée avec un plan de requête très inattendu.
La requête:
SELECT
SQL_NO_CACHE
mbCategory.*
FROM
MBCategory mbCategory
INNER JOIN ResourcePermission as rp
ON rp.primKey = mbCategory.categoryId
where mbCategory.groupId = 12345 AND mbCategory.parentCategoryId = 0
limit 20;
MBCategory - contient 216583 lignes
ResourcePermission - contient 3098354 lignes.
Dans MBCategory j'ai plusieurs index (ordre des colonnes comme dans l'index):
Primary (categoryId)
A (groupId,parentCategoryId,categoryId)
B (groupId,parentCategoryId)
En ResourcePermission j'ai plusieurs index (ordre des colonnes comme dans l'index):
Primary - on some column
A (primKey).
Quand je regarder dans le plan de requête Mysql change la séquence des tables et sélectionne les lignes de ResourcePermission au début, puis il rejoint la table MBCategory (idée folle) et cela prend des âges. J'ai donc ajouté STRAIGHT_JOIN
pour forcer le moteur InnoDB utiliser la séquence de table correcte:
SELECT
STRAIGHT_JOIN SQL_NO_CACHE
mbCategory.*
FROM
MBCategory
mbCategory
INNER JOIN ResourcePermission as rp
ON rp.primKey = mbCategory.categoryId
where mbCategory.groupId = 12345 AND mbCategory.parentCategoryId = 0
limit 20;
Mais ici le deuxième problème materialzie: Dans mon mysql avis devrait utiliser index A (primKey)
sur la jointure opération au lieu qu'il effectue Range vérifié pour chaque enregistrement (carte d'index: 0x400) et il prend encore des âges! L'index de forçage n'aide pas, mysql effectue toujours la vérification de la plage pour chaque enregistrement.
Il n'y a que 23 lignes dans la catégorie MB remplissant les critères, et après la jointure, il n'y a que 75 lignes. Comment puis-je faire mysql pour choisir l'index correct sur cette opération?
Je pense que MySQL ne peut pas déterminer directement combien de lignes il doit lire pour trouver 20 lignes correspondantes; il choisit donc la plus grande table pour 20 matchs puis effectue la jointure interne. Que se passe-t-il si vous supprimez la limite? –
La suppression de la limite ne change rien. J'ai simplement besoin de mysql pour utiliser l'index correct et non le contrôle de plage –