Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/259.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
Php 使用GROUP BY时MySQL查询太慢_Php_Mysql - Fatal编程技术网

Php 使用GROUP BY时MySQL查询太慢

Php 使用GROUP BY时MySQL查询太慢,php,mysql,Php,Mysql,我有两个表格:posts和categories。 posts表大约有360000行 我只想显示每个类别的第一篇文章,按日期排序并使用分页 查询: SELECT * FROM (SELECT * FROM posts ORDER BY date_post DESC) as temp GROUP BY id_category ORDER BY date_post DESC LIMIT $offset, $limit" 加载和显示我的网站大约需要1分钟的时间 我尝试将MyIS

我有两个表格:
posts
categories
posts表
大约有360000行

我只想显示每个类别的第一篇文章,按日期排序并使用分页

查询:

SELECT * FROM 
   (SELECT * FROM posts ORDER BY date_post DESC) as temp 
   GROUP BY id_category ORDER BY date_post DESC 
   LIMIT $offset, $limit"
加载和显示我的网站大约需要1分钟的时间

我尝试将MyISAM改为InnoDB,并使用分区,但没有成功

网站托管的服务器是一个专用服务器,我相信问题不在于它


有人有什么建议吗?

您可以将查询简化如下:

   SELECT * 
   FROM posts
   GROUP BY id_category
   ORDER BY date_post DESC 
   LIMIT $offset, $limit

我不确定您试图通过子查询实现什么。也不确定是否需要GROUP BY,但将其保留在那里。

您需要重构查询:

SELECT posts.* FROM
(
    SELECT id_category,MAX(date_post) date_post
    FROM posts GROUP BY id_category
) postkeys LEFT JOIN posts USING (id_category,date_post);
这将为您提供每一个产品以及该产品的最新帖子

警告 我故意将LIMIT子句移动到子查询中,以生成所需的ID范围。这工作非常,非常快

我在YouTube视频中学习了这项技术:

我将此应用于我在StackOverflow中回答的一个帖子问题:


试试看

您的查询不正确,因为您正在使用,并且这些列的值可能无法确定(您不能保证您将获得第一篇文章)

不知道是否更快,但如果您确定没有多篇文章具有相同的时间戳,您可以使用以下方法:

SELECT posts.*
FROM
  posts INNER JOIN (
    SELECT
      id_category, MAX(date_post) mx_date
    FROM
      posts
    GROUP BY
      id_category
  ) mx ON posts.id_category=mx.id_category
          AND posts.date_post=mx.mx_date
ORDER BY
  posts.date_post DESC
LIMIT $offset, $limit
请看小提琴


当然,请确保您在
id\u category
date\u post
上都有索引。如果你想考虑一个以上的帖子可以共享同一个时间戳的事实,我们需要一个ID,我们需要再添加一个连接。< /P>如果没有太多的类别,那么最好是为每个类别写一个查询。在查询中没有聚合函数,因此在这个上下文中GROUBY是多余的。也许你的意思是DISTINCT?就目前的情况而言,为什么不直接使用SELECT*FROM posts作为临时文件,而不是在其中添加第二个SELECT?我已经尝试了DISTINCT,但我需要回显多个列。。使用DISTINCT,我无法显示所有列,我想问您是否确定DB是瓶颈?也就是说,页面是否按预期通过更简单的查询加载?+1-
groupby
将为每个id\u类别记录返回一条记录。这正是她想要的,所以它是必需的。实际上,对于每个类别的第一篇文章,它应该是
ASC
。我已经尝试过这种方法,但效果太慢了。。无论如何,谢谢!:它工作了,但仍然很慢。。看,问题不是我收到的数据,而是处理的时间。无论如何,谢谢你:D@AllissonFerreira您的查询通常可以正常工作,但并没有文档记录,若您更改平台或升级服务器,可能会返回错误的数据。在这里,你唯一能做的就是使用索引来提高性能。几乎做到了!加载时间约为10秒。。但我注意到,查询每天显示一些帖子。我昨天注册了10种不同类别的产品,应该先展示这20种产品,但只展示了3种。。昨天注册了20种不同类别的产品,只显示了6种。我有一个输入错误,上面写着“按id分组”\u category。我把它改成了
按id\u分类分组
。请再试一次……我看到,当我尝试您的代码时,我在测试之前对其进行了更改:PI再次更改了查询。我在子查询外移动了订单。现在订单看起来完全是随机的,它显示的是2月、3月、1月注册的产品。。我尝试将限制与ORDER BY一起移动到子查询之外,也尝试将ORDER BY IN和限制移动到子查询之外。。这两个尝试的结果与您的第一个提示相同。