SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 10.02.2011 15:27:43

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Работа оптимизатора в разных версиях

Съехали с 5.0.91 на 5.1.52 и с толкнулись с жутким тормозом некоторых запросов. Определили причину - если в клаузах числовые значения (числовых полей) указывать в кавычках, то оптимизатор перерывает весь составной индекс, вместо крайних левых полей.

Все скрипты все значения обрамляют кавычками. Как побороть? Можно ли что-то в конфиг прописать?


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#2 11.02.2011 00:23:21

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Работа оптимизатора в разных версиях

Честно говоря, не понял, что значит «перерывает весь составной индекс».
Строки приводятся к числам достаточно просто, в конфиг ничего для этого
прописывать не надо.

Можете привести пример запроса и EXPLAIN?

Неактивен

 

#3 11.02.2011 11:09:26

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Работа оптимизатора в разных версиях

В нашем случае строки к числам или не приводятся или приводятся как-то не стандартно smile Обращаем внимание на то, что я выделил жирным smile

mysql> explain SELECT COUNT( DISTINCT ( users_numbers.number_id ) ) AS numbers FROM users_numbers WHERE users_numbers.base_id IN ( 16655 ) AND users_numbers.user_id = 10188 AND users_numbers.number_id NOT IN (  SELECT stoplist.number_id FROM stoplist WHERE stoplist.user_id IN ( 0, 10188 ) ) GROUP BY users_numbers.user_id;
+----+--------------------+---------------+-------+-----------------+---------+---------+-------+------+--------------------------+
| id | select_type        | table         | type  | possible_keys   | key     | key_len | ref   | rows | Extra                    |
+----+--------------------+---------------+-------+-----------------+---------+---------+-------+------+--------------------------+
|  1 | PRIMARY            | users_numbers | ref   | user_id,base_id | base_id | 4       | const | 9646 | Using where              |
|  2 | DEPENDENT SUBQUERY | stoplist      | range | PRIMARY         | PRIMARY | 4       | NULL  |   38 | Using where; Using index |
+----+--------------------+---------------+-------+-----------------+---------+---------+-------+------+--------------------------+
2 rows in set (0.00 sec)

mysql> EXPLAIN SELECT COUNT( DISTINCT ( `users_numbers`.`number_id` ) ) AS `numbers` FROM `users_numbers` WHERE `users_numbers`.`base_id` IN ( 16655 ) AND `users_numbers`.`user_id` = '10188' AND `users_numbers`.`number_id` NOT IN (  SELECT `stoplist`.`number_id` FROM `stoplist` WHERE `stoplist`.`user_id` IN ( 0, '10188' ) ) GROUP BY `users_numbers`.`user_id`;
+----+--------------------+---------------+-------+-----------------+---------+---------+-------+-------+-----------------------------+
| id | select_type        | table         | type  | possible_keys   | key     | key_len | ref   | rows  | Extra                       |
+----+--------------------+---------------+-------+-----------------+---------+---------+-------+-------+-----------------------------+
|  1 | PRIMARY            | users_numbers | ref   | user_id,base_id | base_id | 4       | const |  9646 | Using where; Using filesort |
|  2 | DEPENDENT SUBQUERY | stoplist      | index | PRIMARY         | PRIMARY | 12      | NULL  | 83528 | Using where; Using index    |
+----+--------------------+---------------+-------+-----------------+---------+---------+-------+-------+-----------------------------+
2 rows in set (0.00 sec)

Разница в запросах только в наличии кавычек. Структура таблицы подзапроса следующая:

CREATE TABLE `stoplist` (
  `user_id` int(10) unsigned NOT NULL,
  `number_id` bigint(20) unsigned NOT NULL,
  PRIMARY KEY (`user_id`,`number_id`)
) ENGINE=MyISAM;


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#4 11.02.2011 12:05:59

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Работа оптимизатора в разных версиях

Интересно, что с подзапросом это зависимый подзапрос, а с левым объединением
была бы просто табличка wink

Как Вы думаете, какой тип данных у «0»? А у «'10188'»? А у «(0, '10188')»?

Но глобально может быть и ошибка, да.

Неактивен

 

#5 11.02.2011 12:19:53

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Работа оптимизатора в разных версиях

paulus написал:

Интересно, что с подзапросом это зависимый подзапрос, а с левым объединением
была бы просто табличка wink

Джоин был раньше, жутко тормозил и на практике финт с подзапросом оказался быстрее wink
Но дело даже не в этом, проблема наблюдается при выполнении данного подзапроса в качестве отдельного запроса.

paulus написал:

Как Вы думаете, какой тип данных у «0»? А у «'10188'»? А у «(0, '10188')»?

А вот это уже интересно... ('0', '10188') отработал как надо, за подсказку спасибо.

paulus написал:

Но глобально может быть и ошибка, да.

Тем не менее, вариант с (0, '10188') на старом сервере не имеет таких проблем, как на новом, значит всё же разница в поведении оптимизатора имеется smile


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#6 11.02.2011 22:09:27

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Работа оптимизатора в разных версиях

Разница не в поведении оптимизатора. Разница в том, что старые ошибки чинятся,
и, если Вы на них полагались, код перестает работать smile

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson