2010-10-14 4 views
0

je les deux requêtes (*), qui ne diffèrent que dans le domaine étant limité dans la clause WHERE (name1 vs name2) suivants:L'optimisation des requêtes MySQL me rend fou! Presque même, mais horriblement différent

SELECT A.third_id, COUNT(DISTINCT B.fourth_id) AS num 
FROM first A 
JOIN second B ON A.third_id = B.third_id 
WHERE A.name1 LIKE 'term%' 

SELECT A.third_id, COUNT(DISTINCT B.fourth_id) AS num 
FROM first A 
JOIN second B ON A.third_id = B.third_id 
WHERE A.name2 LIKE 'term%' 

Les deux name champs ont un unique index de colonne sur eux. Il y a aussi un index sur les deux colonnes third_id ainsi que fourth_id (qui sont toutes les clés étrangères dans d'autres tables, mais ce n'est pas pertinent ici).

Selon EXPLAIN, le premier se comporte comme celui-ci - qui est ce que je veux:

+----+-------------+-------+-------+---------------+----------+---------+---------------+------+-------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref   | rows | Extra  | 
+----+-------------+-------+-------+---------------+----------+---------+---------------+------+-------------+ 
| 1 | SIMPLE  | A  | range | third_id,name | name  | 767  | NULL   | 3491 | Using where | 
| 1 | SIMPLE  | B  | ref | third_id  | third_id | 4  | db.A.third_id | 16 |    | 
+----+-------------+-------+-------+---------------+----------+---------+---------------+------+-------------+ 

Le second fait cela, que je ne doute pas veulent:

+----+-------------+-------+------+----------------+----------+---------+---------------+--------+-------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref   | rows | Extra  | 
+----+-------------+-------+------+----------------+----------+---------+---------------+--------+-------------+ 
| 1 | SIMPLE  | B  | ALL | third_id  | NULL  | NULL | NULL   | 507539 |    | 
| 1 | SIMPLE  | A  | ref | third_id,name2 | third_id | 4  | db.B.third_id |  1 | Using where | 
+----+-------------+-------+------+----------------+----------+---------+---------------+--------+-------------+ 

Que diable se passe-t-il ici? Comment puis-je faire en sorte que le second se comporte correctement (c'est-à-dire comme le premier)?

(*) En fait, je ne le fais pas. J'ai des requêtes un peu plus complexes; J'ai éliminé les extras pour ce post, et les ai distillés aux requêtes minimales qui présentent toujours le comportement problématique. En outre, les noms ont été changés pour protéger les coupables.

Répondre

2

Ajoutez des instructions CREATE TABLE à votre publication. Une instruction SELECT réelle serait également utile.

Une raison possible est que name2 a un pourcentage de valeurs beaucoup plus élevé commençant par «term%».

Essayez d'appliquer l'ordre des tables dans la requête à l'aide de STRAIGHT_JOIN.

SELECT A.third_id, COUNT(DISTINCT B.fourth_id) AS num 
FROM first A 
STRAIGHT_JOIN second B ON A.third_id = B.third_id 
WHERE A.name2 LIKE 'term%'