我有一个POSTS表,结构是这样的:
CREATE TABLE IF NOT EXISTS `posts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8_turkish_ci DEFAULT NULL,
`content` longtext COLLATE utf8_turkish_ci,
`excerpt` longtext COLLATE utf8_turkish_ci,
`link` longtext COLLATE utf8_turkish_ci,
`original_link` longtext COLLATE utf8_turkish_ci,
`mime_type` longtext COLLATE utf8_turkish_ci,
`language_id` int(11) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
`site_id` int(11) DEFAULT NULL,
`type` varchar(255) COLLATE utf8_turkish_ci DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`modified_at` datetime DEFAULT NULL,
`is_deleted` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `type` (`type`),
KEY `created_at` (`created_at`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_turkish_ci AUTO_INCREMENT=52487 ;和一个USERS表,结构如下:
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) COLLATE utf8_turkish_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_turkish_ci AUTO_INCREMENT=9422 ;我使用这个查询来获得最新的“页面、文件或帖子”帖子,按降序时间排序,并按用户分组,以不显示用户的所有最新帖子:
SELECT p.*, u.*
FROM posts p
LEFT JOIN users u ON p.user_id = u.id
WHERE p.type IN ('post', 'page', 'file')
GROUP BY p.user_id
ORDER BY p.created_at DESC
LIMIT 30但它太慢了,甚至限制为30条记录。
现在,我怎样才能加速这个查询呢?要索引哪些列或任何其他想法?谢谢。
发布于 2011-03-08 08:48:40
首先要做的是在posts.user_id (或者posts.user_id + posts.type)上添加一个索引。和posts.created_at上的另一个索引
更新
我刚刚注意到,您的查询从两个表中获取了所有字段,并且posts表有6个长文本列。所以我认为您的性能很差,因为mysql必须创建一个相当大的临时表或临时文件来获取满足group by + order by子句的所有行。我认为下面的查询应该会有所帮助。
SELECT u.*, p1.* FROM
users u
INNER JOIN
(
SELECT p.user_id, p.created_at, p.id FROM posts p
WHERE p.type IN ('post', 'page', 'file') GROUP by p.user_id
ORDER BY p.created_at DESC LIMIT 30
)xxx ON xxx.user_id = u.id
INNER JOIN posts p1 ON (p1.id = xxx.id)发布于 2011-03-08 08:50:07
在索引方面,我建议在posts.type (WHERE),posts.created_at (ORDER)上创建索引。这应该有助于加快排序速度。
发布于 2011-03-08 08:51:43
您可以尝试这样做:
选择p.,u。
FROM (SELECT \* FROM posts WHERE p.type IN ('post', 'page', 'file')) p左加入p.user_id = u.id上的用户u
GROUP BY p.user\_id ORDER BY p.created\_at DESC LIMIT 30 MySQL首先处理内部查询,然后使用其结果处理记录较少的外部查询。
https://stackoverflow.com/questions/5227079
复制相似问题