Здравствуйте!
Не могу разобраться, как оптимизировать скорость GROUP BY при объединении таблиц.
(версия сервера: 5.1.51)
Есть следующая таблица:
CREATE TABLE IF NOT EXISTS `tags_objects` (
`obj_id` mediumint(8) unsigned NOT NULL,
`tag_id` mediumint(8) unsigned NOT NULL,
KEY `tag_obj` (`tag_id`,`obj_id`),
KEY `obj_tag` (`obj_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=cp1251;
В ней ~250 000 записей, ~125 000 уникальных obj_id, ~200 уникальных tag_id
На каждый obj_id в среднем 2 tag_id
Запрос:
SELECT SQL_NO_CACHE t2.tag_id
FROM tags_objects AS t1, tags_objects AS t2
WHERE 1
AND t1.tag_id IN ( 3, 67, 66, 58, 53, 17, 16, 15, 14, 70, 72, 73, 74 )
AND t1.obj_id = t2.obj_id
GROUP BY t2.tag_id
Результат 100 строк, запрос занял 0.2780 сек.
(А если убрать GROUP BY то результат 72,256 строк, запрос занял 0.0014 сек.)
EXPLAIN:
+----+-------------+-------+-------+-----------------+---------+---------+-----------+-------+----
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
+----+-------------+-------+-------+-----------------+---------+---------+-----------+-------+----
| 1 | SIMPLE | t1 | range | tag_obj,obj_tag | tag_obj | 3 | NULL | 61569 | Using where; Using index; Using temporary; Using filesort
| 1 | SIMPLE | t2 | ref | obj_tag | obj_tag | 3 | t1.obj_id | 1 | Using index
+----+-------------+-------+-------+-----------------+---------+---------+-----------+-------+----
Пробовал использовать комбинации индексов, но они почему-то медленней
(если я правильно понимаю EXPLAIN, то он использует только первые части индексов?):
(`tag_id`) и (`obj_id`,`tag_id`) - 0.5002 сек.
(`tag_id`,`obj_id`) и (`obj_id`) - 0.4464 сек.
(`tag_id`) и (`obj_id`) - 0.5149 сек.
Я так понимаю что для совершения "GROUP BY" MySQL использует "Using temporary; Using filesort",
из за чего и запрос такой медленный, а вот как ускорить так и не нашел
Отредактированно IDr (03.12.2010 20:46:23)