Оптимизация GROUP BY - PullRequest
       26

Оптимизация GROUP BY

0 голосов
/ 28 августа 2009

Эй. Я получил эти две таблицы в соотношении 1: n.

CREATE TABLE IF NOT EXISTS `de_locations` (
`id` int(11) NOT NULL auto_increment,
`user_id` int(11) default NULL,
`author_id` int(11) NOT NULL,
`city_id` int(11) NOT NULL,
`district_id` int(11) NOT NULL,
`title` varchar(150) collate utf8_unicode_ci NOT NULL,
`description` tinytext collate utf8_unicode_ci,
`lat` double NOT NULL,
`lng` double NOT NULL,
`stars` double default '0',
`comments` mediumint(9) default '0',
`flag` tinyint(4) default '0',
PRIMARY KEY  (`id`),
KEY `user_id` (`user_id`),
KEY `flag` (`flag`),
KEY `rating_district` (`district_id`,`stars`,`comments`),
KEY `rating_city` (`city_id`,`stars`,`comments`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=15 ;

и

CREATE TABLE IF NOT EXISTS `de_location2category` (
`id` int(11) NOT NULL auto_increment,
`location_id` int(11) NOT NULL,
`cat_id` mediumint(9) NOT NULL,
PRIMARY KEY  (`id`),
UNIQUE KEY `rel` (`location_id`,`cat_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=14 ;

Местоположение может быть размещено в нескольких категориях.

Например:

Расположение: "Пицца Хат" Категории: "Итальянская еда", "Фастфуд"

Эти категории являются дочерними категориями родительской категории продуктов питания.

Теперь я хочу выбрать все места в категории еда.

SELECT a.id, a.title, a.description, a.street, a.hnr, ROUND(a.stars) as stars, a.comments, a.lat, a.lng
FROM de_locations as a 
INNER JOIN de_location2category as b
ON b.location_id = a.id
WHERE b.cat_id BETWEEN 0 AND 100 
AND a.city_id = 1000 
GROUP BY a.id
ORDER BY a.stars DESC, a.comments DESC

Мне нужна GROUP BY, потому что я не хочу дублировать местоположения, если они связаны с несколькими категориями Но этот запрос строит временную таблицу и использует файловую сортировку. Если я покину GROUP BY, все будет хорошо, но мне это нужно ...

Должен ли я добавить еще один индекс? Или что-то не так с моей схемой? Как бы вы решили эту проблему? Большое спасибо.

Ответы [ 2 ]

1 голос
/ 29 декабря 2010

Я думаю, что ваша проблема в том, что запрос медленный. Не нужно беспокоиться о временных файлах и сортировке файлов, но почему запрос медленный. Добавьте вывод EXPLAIN {yourquery}, чтобы мы могли проверить, что именно происходит.

Или вы также можете попробовать подзапрос:

SELECT a.id, a.title, a.description, a.street, a.hnr, ROUND(a.stars) as stars, a.comments, a.lat, a.lng
FROM de_locations as a 
WHERE 
a.id IN (SELECT DISTINCT b.location_id FROM de_location2category as b WHERE b.cat_id BETWEEN 0 AND 100)
AND a.city_id = 1000 
GROUP BY a.id
ORDER BY a.stars DESC, a.comments DESC
0 голосов
/ 28 августа 2009

Почему бы просто не использовать DISTINCT a.id?

...