Задавайте вопросы, мы ответим
Вы не зашли.
Съехали с 5.0.91 на 5.1.52 и с толкнулись с жутким тормозом некоторых запросов. Определили причину - если в клаузах числовые значения (числовых полей) указывать в кавычках, то оптимизатор перерывает весь составной индекс, вместо крайних левых полей.
Все скрипты все значения обрамляют кавычками. Как побороть? Можно ли что-то в конфиг прописать?
Неактивен
Честно говоря, не понял, что значит «перерывает весь составной индекс».
Строки приводятся к числам достаточно просто, в конфиг ничего для этого
прописывать не надо.
Можете привести пример запроса и EXPLAIN?
Неактивен
В нашем случае строки к числам или не приводятся или приводятся как-то не стандартно Обращаем внимание на то, что я выделил жирным
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;
Неактивен
Интересно, что с подзапросом это зависимый подзапрос, а с левым объединением
была бы просто табличка
Как Вы думаете, какой тип данных у «0»? А у «'10188'»? А у «(0, '10188')»?
Но глобально может быть и ошибка, да.
Неактивен
paulus написал:
Интересно, что с подзапросом это зависимый подзапрос, а с левым объединением
была бы просто табличка
Джоин был раньше, жутко тормозил и на практике финт с подзапросом оказался быстрее
Но дело даже не в этом, проблема наблюдается при выполнении данного подзапроса в качестве отдельного запроса.
paulus написал:
Как Вы думаете, какой тип данных у «0»? А у «'10188'»? А у «(0, '10188')»?
А вот это уже интересно... ('0', '10188') отработал как надо, за подсказку спасибо.
paulus написал:
Но глобально может быть и ошибка, да.
Тем не менее, вариант с (0, '10188') на старом сервере не имеет таких проблем, как на новом, значит всё же разница в поведении оптимизатора имеется
Неактивен
Разница не в поведении оптимизатора. Разница в том, что старые ошибки чинятся,
и, если Вы на них полагались, код перестает работать
Неактивен