首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用GROUP BY和ORDER BY优化查询

如何使用GROUP BY和ORDER BY优化查询
EN

Stack Overflow用户
提问于 2011-03-08 08:44:11
回答 4查看 597关注 0票数 2

我有一个POSTS表,结构是这样的:

代码语言:javascript
复制
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表,结构如下:

代码语言:javascript
复制
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 ;

我使用这个查询来获得最新的“页面、文件或帖子”帖子,按降序时间排序,并按用户分组,以不显示用户的所有最新帖子:

代码语言:javascript
复制
   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条记录。

现在,我怎样才能加速这个查询呢?要索引哪些列或任何其他想法?谢谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-03-08 08:48:40

首先要做的是在posts.user_id (或者posts.user_id + posts.type)上添加一个索引。和posts.created_at上的另一个索引

更新

我刚刚注意到,您的查询从两个表中获取了所有字段,并且posts表有6个长文本列。所以我认为您的性能很差,因为mysql必须创建一个相当大的临时表或临时文件来获取满足group by + order by子句的所有行。我认为下面的查询应该会有所帮助。

代码语言:javascript
复制
  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)
票数 2
EN

Stack Overflow用户

发布于 2011-03-08 08:50:07

在索引方面,我建议在posts.type (WHERE),posts.created_at (ORDER)上创建索引。这应该有助于加快排序速度。

票数 0
EN

Stack Overflow用户

发布于 2011-03-08 08:51:43

您可以尝试这样做:

选择p.,u。

代码语言:javascript
复制
  FROM (SELECT \* FROM posts WHERE p.type IN ('post', 'page', 'file')) p

左加入p.user_id = u.id上的用户u

代码语言:javascript
复制
 GROUP BY p.user\_id   ORDER BY p.created\_at DESC     LIMIT 30 

MySQL首先处理内部查询,然后使用其结果处理记录较少的外部查询。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5227079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档