2009-08-19 7 views
2

J'ai une requête dans une grande table MySQL (> 4 millions de lignes). Cette requête est utilisée dans une procédure stockée et elle recherche par nom de famille et un autre champ numérique. Lorsque j'utilise différentes combinaisons de ces paramètres de recherche, j'obtiens des résultats rapides (entre 1 et 2) mais avec des valeurs particulières, j'obtiens une requête qui prend 9s pour retourner les résultats sur le site de production. Voici ce que je suis sorti de la EXPLAIN:MySQL requête lente dans de rares cas, même si l'index est utilisé

 
id, select_type, table, type, possible_keys, key,  key_len, ref, rows, Extra 
-------------------------------------------- 
1, SIMPLE,  Names, ref, IX_Name,  IX_Name, 17,  const, 3173, Using where 

Surame est déclarée comme varchar (40) et l'autre champ est smallint non signé (6). L'index qui est utilisé est IX_Name qui se compose des préfixes de nom de famille (15) et prénom (10)

Je ne suis pas sûr de ce que je peux faire pour améliorer la performance. Y a-t-il quelque chose de sensiblement faux avec la sortie EXPLAIN ci-dessus? La requête ne s'exécute que lentement sur des combinaisons rares du nom de famille et de l'autre champ, mais elle est cohérente en ce sens qu'elles sont toujours les mêmes requêtes lentes.

J'ai essayé de supprimer tous les index et les ai recréés, mais cela n'a pas résolu les requêtes problématiques.

Le plan de requête montre que l'index est utilisé et sur différents noms de famille (et diverses valeurs pour l'autre champ numérique), la requête peut être instantanée. Cependant, il n'aime pas quand je cherche le nom de famille "Fischer" et une valeur particulière pour le champ numérique (c'est une requête lente particulière). Serait-ce parce qu'il y a beaucoup de noms "Fischer" dans ma table? (environ 3500). Mais dans ce cas, que peut-on faire pour optimiser cette requête? Voici le schéma de ma table. Numéro de nom: Clé primaire, int, unsigned, not null, auto inc; nom de famille: varchar (40); prénom: varchar (40); f3: varchar (40); f4: varchar (40); f5: smallint (6), non signé; f6: smallint (6), non signé; f7: varchar (40); f8: varchar (40); f9: smallint (6); f10: varchar (10); f11: tinyint (4); f12: smallint (6), non signé; F13: texte

La requête que je suis en cours d'exécution est le suivant:

SELECT namenumber,surname,forename,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13 
FROM names IGNORE INDEX (IX_IGNORE1,IX_IGNORE2,IX_IGNORE3) 
WHERE ((surname = 'fischer')) AND (f12 = 270) 
LIMIT 0,14 

MySQL utilise l'index suivant (ix_name) qui comprend les champs suivants: nom de famille (15), prenom (10), soit un 15 préfixe char du nom de famille et 10 préfixe char du prénom.

Pour la plupart des requêtes, c'est très rapide, mais pour les rares, il faut environ 9 secondes pour renvoyer les résultats à la page Web, montrant la sortie d'EXPLAIN comme ci-dessus.

Des idées?

Merci à l'avance, TM

Répondre

1

Avez-vous essayé de modifier l'index ix_name en utilisant uniquement le nom de famille. Il est possible que l'index provoque le retard, car il renvoie les lignes en fonction du nom de famille et du prénom (qui ne fait pas partie de votre requête) et n'a besoin que des parties du contenu réel de la colonne.

+0

Ah Je pensais que c'était un avantage que vous pouvez utiliser un préfixe le plus à gauche de l'index. La chose est que je voudrais être capable de gérer les cas lorsque l'utilisateur entre aussi un prénom. Jamais essayé sans indexer le prénom ... Je vais essayer de le retirer et de tester pour voir comment ça se passe. Merci pour votre réponse. – TMM

Questions connexes