【问题标题】:Mysql php count number of inner join work faster with subqueriesMysql php count 内部连接的数量使用子查询更快
【发布时间】:2015-10-30 11:17:21
【问题描述】:

两个表,第一个是users,第二个是posts,表posts结构是id,body,parent_id,user_id在这个表中所有的posts都插入了parent_id为null,如果是评论则parent_id设置为post id。

我要做的是加入 users 表 - 以获取用户详细信息 - 并获取每个帖子上的 cmets 计数。

我尝试了几个查询

select  p.id,
        users.id as 'from_id',
        users.fullname as 'from_fullname',
        users.role as 'from_role',
        users.picture as 'from_picture',
        p.body,
        p.time_posted as 'time_posted',
        p.attachment,
        p.parent_id,
        count(c.id) as counts
from 
    wall p
join   
    users on users.id = p.user_id
left join 
    wall c on c.parent_id = p.id
where 
    p.class_id = 8 and p.parent_id is null
group by 
    p.id
order by
    `counts` ---->EXPLAIN RESULTS

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  p   ref PRIMARY,parent_id,class_id,user_id  parent_id   5   const   49920   Using index condition; Using where; Using temporary; Using filesort
1   SIMPLE  users   eq_ref  PRIMARY PRIMARY 4   ischool.p.user_id   1   NULL
1   SIMPLE  c   ref parent_id   parent_id   5   ischool.p.id    49920   Using index

这一步平均需要大约 2.7 秒才能完成。

虽然我的第二次尝试

select  p.id,
        users.id as 'from_id',
        users.fullname as 'from_fullname',
        users.role as 'from_role',
        users.picture as 'from_picture',
        p.body,
        (select count(*) from wall where parent_id= p.id ) as comments_count,
        p.time_posted as 'time_posted',
        p.attachment,
        p.parent_id
from 
    wall p
left join 
    users on users.id = p.user_id
where 
    p.class_id = 8 and p.parent_id is NULL
order by 
    p.id DESC; --->Explain results

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY p   ref parent_id,class_id  parent_id   5   const   49920   Using where
1   PRIMARY users   eq_ref  PRIMARY PRIMARY 4   ischool.p.user_id   1   NULL
2   DEPENDENT SUBQUERY  wall    ref parent_id   parent_id   5   ischool.p.id    49920   Using index

此查询需要 1.4 秒才能完成

鉴于我使用 MYSQL innodb 并在每个 id 列上都有索引。

  1. 那么有没有更好的方法来获取帖子和评论计数?
  2. 为什么子查询的工作速度比联接快近 2 倍?

【问题讨论】:

  • 任何时候您想了解有关查询性能的任何信息,都必须从 EXPLAIN 和所有相关表的正确 DDL 开始。
  • @Strawberry yp 是这样做的,没有完全理解返回的解释,我将用结果编辑问题
  • 当然大多数时候join会比子查询快,尤其是inner join,在子查询中mysql会在每次主查询迭代中获取所有行,然后在主查询中过滤, while join 查询直接过滤行,只获取通过过滤器的行。
  • 另请注意,更多的索引并不等于更快的性能 - 但更好的索引可能。

标签: php mysql sql-server join


【解决方案1】:

基本上联接比子查询快。一般来说,新开发者更喜欢使用子查询。

查询的执行计划可能会影响性能。几乎所有情况下的查询连接都比子查询快。

基本区别在于子查询执行查询并加载所有数据,然后基于这些数据执行另一个查询。

和连接都是所有表都加载了数据,因此它可以快速执行查询。

在你的查询中,如果你想显示为什么你的子查询比连接更快,请使用“解释”命令来显示查询是如何实际执行的。

以下链接可能有助于理解概念: http://www.chrislondon.co/joins-vs-subqueries/ http://www.sitepoint.com/using-explain-to-write-better-mysql-queries/

【讨论】:

  • ehhm,我已经做了并发布了有问题的解释结果。我看不出你是怎么回答的。
  • 这太简单了,没有用或真实
  • @Strawberry / Zalaboza :您在同一时间发送相同的帖子并且您没有权利不被拒绝并对我的回答投反对票,这不是我的错。
  • 如果你不能像我一样解释事情,那不是我的错。
  • 我已经简单地解释了你想要什么,玩真实的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-20
  • 1970-01-01
  • 2017-08-18
  • 2016-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多