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.