Index MySQL pas utilisé pour chaque requête [Résolu]

Index MySQL pas utilisé pour chaque requête [Résolu] - SQL/NoSQL - Programmation

Marsh Posté le 08-10-2014 à 09:25:50    

Bonjour,  
 
J'ai un souci avec un index sur une table MySQL qui n'est pas utilisé systématiquement dans une requête.  
 
J'ai une table nommée ENTREPOSAGE qui contient 93535 lignes et 75 champs, dont celui-ci :  
 

Code :
  1. Valide enum('N','O') NOT NULL DEFAULT 'N'


 
J'ai créé cet index :  
 

Code :
  1. Nom    Type  Unique Compressé Colonne Cardinalité Null
  2. Valide BTREE Non    Non       Valide  1           Non


 
Quand j'exécute cette requête (sélection des valeurs N) :  
 

Code :
  1. EXPLAIN SELECT * FROM entreposage WHERE Valide = 'N'


 
je constate que l'index est bien utilisé :
 

Code :
  1. id select_type table       type possible_keys key    rows extra
  2. 1  SIMPLE      entreposage ref  Valide        Valide 69   Using index condition


 
Mais quand j'exécute celle-ci (sélection des valeurs O) :  
 

Code :
  1. EXPLAIN SELECT * FROM entreposage WHERE Valide = 'O'


 
l'index est ignoré :  
 

Code :
  1. id select_type table       type possible_keys key  rows  Extra
  2. 1  SIMPLE      entreposage ALL  Valide        NULL 93535 Using where


 
Je ne comprends pas pourquoi :-(  
 
Quelqu'un peut-il m'aider ? Merci !


Message édité par Erwan21 le 08-10-2014 à 09:58:53
Reply

Marsh Posté le 08-10-2014 à 09:25:50   

Reply

Marsh Posté le 08-10-2014 à 09:37:45    

Quel est le ratio entre le nb d'enregistrements avec Valide = O et valide  = N ?
En effet, si je me souviens bien, si Mysql constate que l'utilisation de l'index ramène plus de 30% (pas complètement sûr de cette valeur, mais c'est l'ordre de grandeur) de la table complète, elle laisse tomber l'index et fait un full scan.
 
Avec ton ex, j'aurais tendance à penser que t'as moins de 30% d'enregistrements avec Valide = N. => donc plus de 60% d'enregistrements avec Valide = O, d'où pas d'utilisation de l'index ;)


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 08-10-2014 à 09:43:02    

Merci de ta réponse rapide.
En effet, le ratio est même encore plus déséquilibré : moins de 100 'N' et donc plus de 93000 'O'.
J'avais dans l'idée d'optimiser mes requêtes par la fonction EXPLAIN mais si ce que tu dis est vrai ça n'a pas d'intérêt  :(

Reply

Marsh Posté le 08-10-2014 à 09:49:01    

C'est clair qu'avec un tel ratio, Mysql n'a aucun intérêt à passer par l'index, ça va le ralentir. Autant qu'il scanne toute ta table, ça ira aussi vite. Car là, le temps qu'il charge l'index, qu'il le parcourt et fasse les "sauts" à chaque enregistrement avec un Valide=O, ça mettra clairement plus de temps que de scanner toute la table et vérifier si Valide=O ;)


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 08-10-2014 à 09:57:24    

J'ai compris. Il n'y a donc pas de "bug" :) Et je vais continuer quand même à chercher à optimiser mes requêtes via des index... Merci encore !

Reply

Marsh Posté le 08-10-2014 à 10:02:21    

Une solution serait de faire un index composé de 2 champs : Valide + un autre, suffisamment discriminent pour que les couples "valide+autre champ" soient avec des ratios < 30% ;)


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 08-10-2014 à 10:05:59    

Ah oui, bonne idée ! Je vais voir ça...

Reply

Marsh Posté le 08-10-2014 à 10:11:04    

Juste pour info, voici un extrait de la doc MySQL, exactement ce que tu as dit  :)  
 

Citation :

Notez que dans certains cas, MySQL ne va pas utiliser un index, même s'il y en a un disponible. Si l'utilisation de l'index requiert que MySQL accède à plus de 30% des lignes de la table (dans ce cas, un scan de table est probablement plus rapide, et demandera moins d'accès disques). Notez que si une telle requête utilise la clause LIMIT pour ne lire qu'une partie des lignes, MySQL utilisera tout de même l'index, car il va trouver plus rapidement les quelques lignes de résultat.

Reply

Marsh Posté le 08-10-2014 à 10:19:00    

J'ai eu du bol pour le 30% :sol:


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed