Ici, je vais ajouter une partie de ma question, car il est des informations sensibles et j'utiliser des noms pas réel:MySQL ignorer l'index même avec l'index d'indice d'utilisation ou de force
SELECT
`entity`.`id`,
`entity`.`requirements`,
`entity`.`description`,
`entity`.`status`,
`entity_videos`.`length`,
`entity_videos`.`quality`,
`states`.`name`,
`uploads`.`id`,
`uploads`.`name`
FROM `entity`
LEFT JOIN `states` ON `states`.`id` = `entity`.`state_id`
INNER JOIN `uploads` FORCE INDEX (`uploadable_id_index`)
ON `uploads`.`uploadable_type` = 'Entity'
AND `uploads`.`category` = 'Icon'
AND (`uploads`.`uploadable_id` = `entity`.`id`
OR `uploads`.`uploadable_id` = `entity`.`parent_entity_for_icon`
)
INNER JOIN `entity_videos` FORCE INDEX (entity_videos_entity_id_index)
ON `entity_videos`.`entity_id` = `entity`.`id`
WHERE `entity`.`status` = 'active'
Le problème est que optimiseur Mysql ne veulent pas pour utiliser l'index uploadable_id_index
. Une partie de l'expliquer:
Comme je sais FORCE INDEX
est optimiseur de force à utiliser indice sauf situation optimiseur ne peut pas utiliser l'index. Que dois-je faire pour forcer cet index et ne pas effectuer une analyse complète de la table? J'ai essayé d'enlever entity_videos_entity_id_index
aussi j'ai essayé d'ajouter uploads
l'information de table à la clause where, mais rien ne fonctionne pour moi. Des idées? Merci beaucoup pour toute aide
Mise à jour:
Avec l'aide de @Barmar et @PaulSpiegel je trouve cette question est en (uploads.uploadable_id = entity.id OR uploads.uploadable_id = entity.parent_entity_for_icon)
. Et jouer avec requête pendant un certain temps, je trouve que la meilleure solution dans mon cas est:
SELECT
`entity`.`id`,
`entity`.`requirements`,
`entity`.`description`,
`entity`.`status`,
`entity_videos`.`length`,
`entity_videos`.`quality`,
`states`.`name`,
`icon`.`id`,
`icon`.`name`,
`parent_offer_icon`.`id`,
`parent_offer_icon`.`name`
FROM `entity`
LEFT JOIN `states` ON `states`.`id` = `entity`.`state_id`
LEFT JOIN `uploads` as `icon` FORCE INDEX (`uploadable_id_index`)
ON `icon`.`uploadable_type` = 'Entity'
AND `icon`.`category` = 'Icon'
AND `icon`.`uploadable_id` = `entity`.`id`
LEFT JOIN `uploads` as `parent_offer_icon` FORCE INDEX (`uploadable_id_index`)
ON `parent_offer_icon`.`uploadable_type` = 'Entity'
AND `parent_offer_icon`.`category` = 'Icon'
AND `parent_offer_icon`.`uploadable_id` = `entity`.`parent_entity_for_icon`
INNER JOIN `entity_videos` FORCE INDEX (entity_videos_entity_id_index)
ON `entity_videos`.`entity_id` = `entity`.`id`
WHERE `entity`.`status` = 'active'
AND (parent_offer_icon.id IS NOT NULL
OR icon.id IS NOT NULL)
Je suis toujours ouvert à d'autres suggestions :)
La condition 'de OR' pourrait être le problème. Essayez d'utiliser 'uploadable_id IN (entity.id, entity.parent_entity_for_icon)' – Barmar
@Barmar merci pour une proposition mais cela ne fonctionne pas non plus. Et j'ai oublié, il y a quelques jours quand il y avait beaucoup moins d'enregistrements dans DB optimizer sélectionner cet index, peut-être qu'il est vraiment beaucoup plus rapide de faire un scan complet au lieu d'utiliser un index? –
Habituellement, les index sont plus utiles lorsque la table devient plus grande. Mais peut-être que la cardinalité de cet index est trop faible. Utilisez 'SHOW INDEX FROM uploads 'pour voir. – Barmar