2009-11-11 5 views
0

Je veux optimiser cette requête car il prend de temps pour exécuter presque une secondeOptimize mysql requête

Voici la requête:

IF Exists(
Select CustFirstName From Customers 
    Where (CustFirstName = InputCustFirstName) 
    OR (CustLastName= InputCustLastName) 
    OR (Email = InputEmail) 
); 

Toutes ces trois colonnes ont l'index unique sur elle. et j'ai 765704 enregistrements dedans.

Ceci est le résultat d'expliquer un ensemble de ma requête:

 
----+-------------+-------+------+----------------------+------+---------+------+--------+-----------------------------------+ 
| id | select_type | table | type | possible_keys  | key | key_len | ref | rows | Extra        | 
+----+-------------+-------+------+----------------------+------+---------+------+--------+-----------------------------------+ 
| 1 | SIMPLE  | Customers | ALL | CustName | NULL | NULL | NULL | 765704 | Using where with pushed condition | 
+----+-------------+-------+------+----------------------+------+---------+------+--------+-----------------------------------+ 

Quelqu'un peut-il me aider sur la façon de l'optimiser.

Répondre

1

Une seconde pour interroger trois fois un index de 3/4 millions d'enregistrements et renvoyer l'union des trois requêtes? Cela semble raisonnable, sauf si vous avez un serveur très rapide avec des disques SAS ou SCSI 15K RPM.

Vous pouvez essayer de le recoder en une union de trois requêtes distinctes, une pour chaque critère de colonne. Cela pourrait lui permettre d'utiliser un index pour chaque colonne.

2

Vous n'avez pas assez d'index, semble-t-il. Il n'y a qu'un possible_keys, où vous avez probablement besoin de trois. Avoir un index unique sur tous les trois comme un seul tuple n'est pas suffisant.

Supposons que vous avez indexé les trois colonnes. Where (CustFirstName = InputCustFirstName) OR (CustLastName= InputCustLastName) OR (Email = InputEmail)) va généralement frustrer l'optimiseur de requête.

Modifier le prédicat en utilisant OR à l'aide d'un UNION:

Pour paraphraser votre requête un peu, vous changeriez

SELECT * FROM Customers 
WHERE CustFirstName = InputCustFirstName 
OR CustLastName = InputCustLastName 
OR Email = InputEmail 

à

SELECT * FROM Customers 
WHERE CustFirstName = InputCustFirstName 
UNION 
SELECT * FROM Customers 
WHERE CustLastName = InputCustLastName 
UNION 
SELECT * FROM Customers 
WHERE Email = InputEmail