Оптимизация запросов MySQL сводит меня с ума!Почти такой же, но ужасно другой - PullRequest
0 голосов
/ 14 октября 2010

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

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

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

Ответы [ 2 ]

2 голосов
/ 14 октября 2010

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

1 возможная причина в том, что name2 имеет гораздо более высокий процент значений, начинающихся с "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 голос
/ 14 октября 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...