【问题标题】:MySQL Query Performance - Subquery Vs JoinMySQL 查询性能 - 子查询与联接
【发布时间】:2015-10-07 14:48:39
【问题描述】:

我不是 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;

【问题讨论】:

  • 您是否尝试过将explain 放在查询前面并比较执行计划?
  • @e4c5 但是这个例子是一个子查询,它的性能明显优于连接。
  • @Phylogenesis 哦,对不起,我看错了!
  • 始终使用EXPLAIN(并在此处发布其输出)。如果您有两个对相同数据进行操作的查询,请始终确保您不会通过发出 RESET QUERY CACHE; 来从查询缓存中提取数据。要记住的另一件非常非常重要的事情 - 您可以将 SQL 优化到无限甚至更远,但硬件起着非常重要的作用。了解您正在使用的引擎以及它是否以最佳方式使用您的硬件非常重要。

标签: mysql performance subquery left-join


【解决方案1】:

作为一般规则:

  • 如果子查询“缩小”行数(例如,通过GROUP BYLIMIT),则子查询方法更好。
  • JOIN 通常会创建比原始表更多的行。 DISTINCT 有时用于缩小该行数。
  • 如果外部查询有GROUP BYJOIN可能创建比您意识到的更多的行并“膨胀”任何聚合(SUMCOUNT 等),从而投票代替子查询。
  • 多个子查询会导致优化不佳。 (特此投票给JOIN。)

所有这些都假设最佳索引。

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

INDEX(pay_id, amount, basesalary_id) -- both "covering" and optimal for `WHERE`

请查看EXPLAIN SELECT ... 以获取这两个查询。可能更快的开头是basesalary,然后是INDEX(employee_id),这是非常有选择性的。

看到SHOW CREATE TABLE后,我可能有更多的cmets。

【讨论】:

  • 使用子查询时,解释显示以下序列:1 - 主 - 无键 - 667154 行 - 额外:“使用 where” 2 - 派生 - 无键 - 667154 行 - 额外:无 3 - 派生 - 主键 - 1 行 - 额外:无 使用连接时,解释显示此序列:1 - 简单 - 无键 - 667171 行 - 额外:无 2 - 简单 - 主键 - 1 行 - 额外:使用 where
  • 对不起;太难读了;请编辑您的问题以添加它。
猜你喜欢
  • 1970-01-01
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
相关资源
最近更新 更多