Accueil > Communautés > Le blog > Billets techniques > Des problèmes de performances avec les requètes de type IN ?Archives
- Mai 2008
- Avril 2008
- Mars 2008
- Février 2008
- Janvier 2008
- Décembre 2007
- Novembre 2007
- Octobre 2007
- Septembre 2007
- Août 2007
- Juillet 2007
- Juin 2007
- Mai 2007
- Avril 2007
- Mars 2007
- Février 2007
- Janvier 2007
- Décembre 2006
- Novembre 2006
- Octobre 2006
- Septembre 2006
- Août 2006
- Juillet 2006
- Juin 2006
- Mai 2006
- Avril 2006
- Mars 2006
- Février 2006
- Janvier 2006
- Décembre 2005
- Novembre 2005
- Octobre 2005
- Septembre 2005
- Août 2005
- Juillet 2005
Des problèmes de performances avec les requètes de type IN ?
Par joce le 25 Juillet à 00:42:18
3 commentaire(s)
Martin Friebe, un contributeur très actif de la communauté MySQL s'est rendu compte d'une chose intéressante, notamment pour ceux utilisant de façon intensive des requètes du style IN () contenant beaucoup de valeur :
le code de l'optimizer de MySQL responsable du plan d'execution de type RANGE (utilisé notamment lors des requètes IN) n'est pas optimal, ce qui amène à des performances moins élevées que ce que l'on pourrait escompter.
Le problème devient particulièrement embétant dans MySQL 5.0 lorsque des jointures de ce style sont utilisées :
SELECT a FROM t1,t2 WHERE t1.a=t2.b AND t2.b IN (...)
En effet, MySQL 5.0 et > dispose d'une optimisation appelée "propagation d'égalité", et la requète devient donc après optimisation :
SELECT a FROM t1,t2 WHERE t1.a=t2.b AND t2.b IN (...) AND t1.a IN (...)
Et là, le problème de l'optimizer se fait sentir : en effet, lorsqu'il se trouve en presence de deux IN, il calcule de façon incorrecte que le nombre approximatif de ligne qui va être retourné par la requète est égal au nombre de valeur dans le premier IN * le nombre de valeur dans le deuxième IN, et va faire beaucoup plus de tests que nécessaire... ce qui peut faire particulièrement mal
Et il semble que l'optimizer ait d'autres problèmes s'ajoutant à cela, necessitant une investigation approfondie (voir le bug http://bugs.mysql.com/bug.php?id=20932 )
En bref, la phase de calcul des statistiques peut être jusqu'à 20x plus lente sur de grosse liste !
Il pourrait être donc judicieux, si vous vous trouvez dans ce cas, de créer une temporary table (en memoire) contenant votre liste et de faire une jointure sur cette liste, plutôt que d'utiliser un IN (...) avec énormement de valeurs.
Pour les personnes recherchant les performances à tout prix tout en gardant un IN (...) avec beaucoup de valeurs, ils peuvent jeter un oeil et essayer les patchs suivant :
http://bugs.mysql.com/bug.php?id=26453
http://bugs.mysql.com/bug.php?id=26232
en attendant que MySQL ne les intègre officiellement.
Un hack a été également posté, désactivant la propagation d'égalité dans 5.0 pour les listes contenant plus de 5 éléments :
Code :
|
Commentaires (3)
Joce
le 26 Juillet à 01:46:11
Meme si un BETWEEN utilise aussi le type RANGE au niveau de l'optimizer, je ne pense pas qu'il soit affecté par le probleme :
Il n'y a que deux valeurs qui sont recherchés au niveau de l'index (la borne min et la borne max), alors que pour le IN avec plusieurs valeurs il y a une recherche pour chaque valeur. Donc au niveau de l'optimizer le plan d'execution est très vite décidé, et peu de temps est passé dans la phase "stastistic" dans le cas du BETWEEN.
Fixazo
le 27 Juillet à 14:05:34
Ok, tout ce que je voulais savoir est là
Merci !

Fixazo
le 26 Juillet à 00:28:28
Est-ce qu'on retrouve le même problème avec la clause BETWEEN?