我有这种形式的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
让我感到惊讶的是,速度会有所不同,而较低的查询会更快。我更喜欢上层开发,因为我可以独立运行子查询。
有没有办法让两个世界中最好的"快速的结果返回并且能够单独运行子查询?
答案 0 :(得分:0)
可能,相关子查询能够有效地使用索引,这就是它快速的原因,即使子查询必须多次执行。
对于使用内联视图的第一个查询,导致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
外部联接等效于第二个查询。将SUM()聚合包装在IFNULL
函数中如果在薪水中找不到具有非空值amount
的匹配行,则希望返回零值而不是NULL值。)
答案 1 :(得分:0)
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查询的输入,这就是嵌套查询比连接更快的原因。