У меня есть два следующих запроса (*)
, которые отличаются только полем, ограниченным в предложении WHERE
(name1
против name2
):
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%'
Оба поля name
имеют индекс в одну колонку. Также есть индекс для обоих столбцов third_id
и fourth_id
(которые являются внешними ключами других таблиц, но здесь это не имеет значения).
Согласно EXPLAIN
, первый ведет себя так - вот что я хочу:
+----+-------------+-------+-------+---------------+----------+---------+---------------+------+-------------+
| 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 | |
+----+-------------+-------+-------+---------------+----------+---------+---------------+------+-------------+
Второй делает это, что я определенно делаю не хочу:
+----+-------------+-------+------+----------------+----------+---------+---------------+--------+-------------+
| 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 |
+----+-------------+-------+------+----------------+----------+---------+---------------+--------+-------------+
Какого черта здесь происходит? Как заставить второй вести себя правильно (то есть, как первый)?
(*)
На самом деле, нет. У меня есть немного более сложные запросы; Я удалил дополнения для этого поста и разобрал их до минимальных запросов, которые по-прежнему демонстрируют проблемное поведение. Также были изменены имена, чтобы защитить виновных.