Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何使用GROUP BY和ORDER BY优化查询_Mysql_Sql_Query Optimization - Fatal编程技术网

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

Mysql 如何使用GROUP BY和ORDER BY优化查询,mysql,sql,query-optimization,Mysql,Sql,Query Optimization,我有一个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, `

我有一个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 ;
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 ;
还有一个用户表,结构如下:

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 ;
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条记录以内


现在,我如何加快查询速度?要索引哪些列或其他想法?谢谢。

首先要做的是在posts.user\u id或posts.user\u id+posts.type上添加索引。还有一个关于posts的索引

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

  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)

就索引而言,我建议在posts.type WHERE,posts.created_上创建索引。这将有助于加快排序速度。

您可以尝试以下方法:

选择p,u。 从中选择*从p.所在的帖子中键入“帖子”、“页面”、“文件”p 在p.user\u id=u.id上左加入用户u 按p.user\U id分组按p.created\U在DESC创建的订单 限制30


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

尝试@Gabriel的答案,但在内部查询中有限制

选择p,u。 从SELECT*FROM post,其中键入“post”、“page”、“file”顺序,由DESC LIMIT 30p创建 在p.user\u id=u.id上左加入用户u
由p.U.在创建的订单

这也是我的要求,但OP更新了CREATE表,以显示用户id已被索引:/Yes我为查询中提到的每一列创建了索引,但没有任何更改:它工作起来很有魅力。现在查询只持续了3秒钟,我知道它仍然很遥远,然后bestUsers表有9000多个用户,posts表有50000多个帖子。查询仍然需要7秒钟。没有收获。