繁体   English   中英

SELECT中的子查询或JOIN中的子查询?

[英]Subquery in SELECT or Subquery in JOIN?

我有这种形式的MYSQL查询:

SELECT
    employee.name,
    totalpayments.totalpaid
FROM
    employee
    JOIN (
        SELECT
            paychecks.employee_id,
            SUM(paychecks.amount) totalpaid
        FROM
            paychecks
        GROUP BY
            paychecks.employee_id
         ) totalpayments on totalpayments.employee_id = employee.id

我最近发现这种形式的返回速度更快:

SELECT
    employee.name,
    (
        SELECT
            SUM(paychecks.amount)
        FROM
            paychecks
        WHERE
            paychecks.employee_id = employee.id
    ) totalpaid
FROM
    employee

令我惊讶的是,速度会有所不同,而较低的查询会更快。 我更喜欢上层开发,因为我可以独立运行子查询。

有没有一种方法可以做到“两全其美”:快速返回结果并能够独立运行子查询?

可能,相关子查询能够有效地使用索引,这就是为什么它很快的原因,即使该子查询必须执行多次。

对于使用内联视图的第一个查询,导致MySQL创建派生表 ,对于大型集,这实际上是MyISAM表。

在MySQL 5.6.x和后,优化器可以选择在派生表添加一个索引,如果将允许ref操作和的估计成本ref操作比嵌套循环扫描低。

我建议您尝试使用EXPLAIN查看访问计划。 (根据性能报告,我怀疑您正在MySQL 5.5或更早版本上运行。)


如果employees中有行,而paychecks中没有匹配的行,则这两个语句并不完全相等。

可以完全避免子查询而获得等效结果:

SELECT e.name
     , SUM(p.amount) AS total_paid
  FROM employee e 
  JOIN paychecks p
    ON p.employee_id = e.id
 GROUP BY e.id

(使用内部联接来获得与第一个查询等效的结果,使用LEFT外部IFNULL等效于第二个查询。如果要返回零而不是NULL值,请在IFNULL函数中包装SUM()聚合当在薪水中找不到具有非空值amount匹配行时。)

Join基本上是笛卡尔积,这意味着表A的所有记录将与表B的所有记录组合。输出将是

number of records of table A * number of records of table b =rows in the new table
10 * 10 = 100

在这100条记录中,与过滤器匹配的记录将在查询中返回。

在嵌套查询中,有一个示例内部查询,内部查询的记录总大小将是outter查询的输入,这就是嵌套查询比连接更快的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM