【发布时间】:2009-08-28 10:01:50
【问题描述】:
嘿。我有这两个表的 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 一切都很好,但我需要它……
我必须添加另一个索引吗?还是我的方案有什么问题? 你将如何解决这个问题?非常感谢。
【问题讨论】:
-
"但是这个查询构建了一个临时表并使用了文件排序。"所以呢?这就是关系数据库的工作方式。那有什么问题?您还建议如何删除重复项?
-
dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html "在某些情况下,MySQL 无法使用索引来解析 ORDER BY,尽管它仍然使用索引来查找与 WHERE 子句匹配的行。这些情况包括:您在不同的键上使用 ORDER BY:SELECT * FROM t1 ORDER BY key1, key2;"
-
“这有什么问题?”表现。在简单的 SELECT 中,GROUP BY 并不总是强制临时表。在这种情况下没有办法实现这一点吗? GROUP BY 也不使用索引“rating_city”。
-
嘿,戴夫。是的,我已阅读“按优化排序”文档。但我无法找到解决方案。这根本不可能吗?或者我可以通过更改索引或 SELECT 来获得更好的性能吗?到目前为止感谢
-
黑白分明:如果您使用多个键进行排序,那么您将使用文件排序。
标签: mysql optimization group-by