MySQL查询性能 - 子查询与加入

时间:2015-10-07 14:48:40

标签: mysql performance subquery left-join

我不是SQL专家,所以我试图理解为什么两个查询的执行时间差异很大。

common_stats是一个大表(300万行)。我只是想了解为什么性能上的巨大差异。

以下查询需要约15秒:

select distinct cs.basesalary_id
from common_stats AS cs
LEFT JOIN basesalary AS b ON b.id = cs.basesalary_id
WHERE (b.employee_id= 100 AND cs.amount > 0 AND cs.pay_id is null );

此查询需要〜。1秒:

select distinct basesalary_id from (
    select cs.basesalary_id, cs.pay_id
    from common_stats AS cs
    LEFT JOIN basesalary AS b ON b.id = cs.basesalary_id
    WHERE (b.employee_id= 100 AND cs.amount > 0)
) as temp
where pay_id is null;

1 个答案:

答案 0 :(得分:0)

作为一般规则:

  • 如果子查询收缩'行数(例如,通过parameterGROUP BY),子查询方法更好。
  • LIMIT通常会创建比原始表更多的行。有时用JOIN来缩小行数。
  • 如果外部查询有DISTINCT,则GROUP BY 可能会创建比您实现的更多的行,并且"膨胀"任何聚合(JOINSUM等),从而投票给子查询。
  • 多个子查询会导致优化不佳。 (从而投票给COUNT。)

所有这些都假定最佳指数。

您的第一个查询可能会受益于

JOIN

查看INDEX(pay_id, amount, basesalary_id) -- both "covering" and optimal for `WHERE` 两个查询。可能从EXPLAIN SELECT ...开始的速度越快,basesalary就越快,而且非常有选择性。

在看到INDEX(employee_id)后,我可能会有更多评论。