2010-01-29 8 views
0

Ceci est la structure de la table:mysql optimisation des requêtes

for_id 
from_id 
for_folder 
from_folder 
deleted 

Le nombre représente ma carte d'identité et c'est la requête:

SELECT * 
FROM poruke_konverzacija 
WHERE (
(
for_id =2 
AND for_folder = "inbox" 
) 
OR (
from_id =2 
AND from_folder = "inbox" 
) 
) 
AND deleted !=2 

J'ai près de 500k dossiers sur la table et quand Je cours expliquer, c'est ce que je reçois:

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE poruke_konverzacija ALL obrisano,za_id,od_id NULL NULL NULL 456884 Using where; Using filesort 

J'ai indexé for_id fro m_id for_folder from_folder et la requête est vraiment lente. Y a-t-il un autre moyen de le faire et d'obtenir les mêmes résultats?

Répondre

3

Index supprimé aussi. De même ... Une union peut être meilleure, en exécutant deux requêtes simultanées plutôt qu'une longue.

En outre l'indexation/sélection sur les champs de chaîne est toujours plus lente. Si vous pouvez faire une table pour les dossiers

ie

id ----- folder 
1  inbox 
2  sent 
3  trash 

dans votre table poruke_konverzacija convertir le from_folder et for_folder à l'ID équivalent

SELECT * 
FROM poruke_konverzacija 
WHERE 
for_id =2 
AND for_folder = "inbox" 
AND deleted !=2 
UNION 
SELECT * 
FROM poruke_konverzacija 
WHERE 
from_id =2 
AND from_folder = "inbox" 
AND deleted!=2 
2

De la sortie EXPLIQUER il ressemble mysql n'utilise aucune des clés. C'est parce que vous utilisez OU avec deux champs différents. mysql utilisera l'index pour OU si les conditions utilisent le même champ par exemple. field1 = v1 OU field1 = v2. Il n'utilisera pas d'index si vous utilisez des champs différents dans la condition Voir: http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html.

Essayez avec UNION:

SELECT * 
FROM poruke_konverzacija 
WHERE for_id =2 
    AND for_folder = "inbox" 
    AND deleted !=2 
UNION 
SELECT * 
FROM poruke_konverzacija 
WHERE from_id =2 
    AND from_folder = "inbox" 
    AND deleted !=2