0

我有一个这种形式的 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

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

有没有办法获得“两全其美”:快速结果返回并能够单独运行子查询?

4

2 回答 2

0

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

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

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

在嵌套查询中,有一个示例内部查询,无论内部查询的记录总大小是多少,都将是外部查询的输入,这就是为什么嵌套查询比联接更快的原因。

于 2015-02-11T17:34:37.343 回答
0

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

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

在 MySQL 5.6.x 及更高版本中,优化器可以选择在派生表上添加索引,如果这将允许ref操作并且操作的估计成本ref低于嵌套循环扫描。

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


这两个语句并不完全等价,如果其中有行,employeespaychecks.

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

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 值时将 SUM() 聚合包装在一个函数中amount在 paychecks 中找到具有非 null 值的匹配行。)

于 2015-02-11T17:24:19.603 回答