Оптимизация запросов MySQL сводит меня с ума! Почти такой же, но ужасно другой

0

У меня есть следующие два запроса (*), которые отличаются только в поле, которое ограничено в предложении WHERE (name1 vs 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 | 
+----+-------------+-------+------+----------------+----------+---------+---------------+--------+-------------+

Что, черт возьми, происходит здесь? Как заставить второго вести себя правильно (т.е. Как первый)?

(*) Собственно, я этого не делаю. У меня несколько более сложные запросы; Я удалил дополнительные задания для этого сообщения и перепрофилировал их на минимальные запросы, которые по-прежнему демонстрируют проблемное поведение. Кроме того, имена были изменены для защиты виновных.

Теги:
optimization
indexing

2 ответа

2
Лучший ответ

Добавьте инструкции CREATE TABLE к вашему сообщению. Также будет полезен реальный оператор SELECT.

1 возможная причина заключается в том, что имя2 имеет гораздо больший процент значений, начиная с "term%".

Попробуйте выполнить порядок таблиц в запросе с помощью 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%'
1

Сколько записей в этих таблицах? Проверьте мощность/избирательность в столбце name2.

Если селективность низкая, попробуйте Naktibalda "STRAIGHT_JOIN" или подсказки http://dev.mysql.com/doc/refman/5.0/en/index-hints.html

Ещё вопросы

Сообщество Overcoder
Наверх
Меню