首页 > 解决方案 > 哪个查询有更好的性能?

问题描述

我有3个表如下:

class
  id:bigint(PK)
  name:varchar


principal:
  id: bigint(PK)
  pid:bigint
  flag:boolean
  uniqueConstraint(pid, flag)

entry:
  cid: (FK, reference class)
  pid: (FK, refernce principal)
  object_id: bigint
  code: tinyint
  PK: (cid, pid, obj)

查询必须使用参数集检查条目中是否存在记录。

假设参数集如下:

我写了 2 个查询,一个使用join一个使用sub-query

查询编号 1:

select id from entry where pid in
    (select id from principal
         where (pid=2 AND role)
            OR (pid=3 AND !role)
    )
    AND cid = (select id from class where name='Class#3')
    AND object_id=45

和查询号 2:

select e.id from class c
            inner join entry e on e.cid=c.id and c.name='Class#3'
            inner join principal p on p.id=e.pid 
                     and p.id in ( select id from principal
                         where (pid=2 AND role)
                            OR (pid=3 AND !role)
                                 )
    where e.object_id=45

当然还有一个额外的条件来检查我没有在查询中包含的代码。

我想知道哪一个在大规模生产环境中表现更好。假设类中有 100 行,主体有 10000 行,“条目”中有超过 250000 行,并且必须为每个请求执行查询(如解释),并且至少有 3000 个用户在系统上不断地同时工作。

  1. 这些查询中的哪一个会执行得更好,为什么?原因对于进一步的工作非常重要
  2. 有没有比这两种方法更好的方法来编写查询,或者甚至更好的方法来构造模式?

问候


PS:我已经阅读过这个关于比较子查询和连接的问题,但我的问题并不完全是一个简单的比较

标签: mysqlquery-performancemysql-5.7

解决方案


IN ( SELECT ... )通常是低效的。

OR通常是低效的。

JOINs通常比其他表达方式更有效。

这个

     where (pid=2 AND role)
        OR (pid=3 AND !role)

这样可能会更快:

     where pid IN (2,3)
       AND ((pid=2 AND role)
         OR (pid=3 AND !role)
           )

如果可以有效地使用索引来限制在执行此操作之前OR对 2 和 3 的努力,则可能会加快速度。

尝试其他人评论的内容和我的建议,并提供CREATETABLE 和EXPLAIN. 然后我可以就索引提出建议。


推荐阅读