首页 > 解决方案 > 这两个 SQL 查询之间是否存在性能差异?

问题描述

我是一个新的 SQL 学习者和 StackOverflow 的新手。希望我没有错过任何重要的第一次发帖。

我碰巧从我的教练那里得到两个以下查询,说他们有不同的表现。但我不明白为什么它们在逻辑和计算成本方面有所不同。

查询一:

SELECT First_Name,
SUM(total_sales_amount) AS sub_total_sales_amount  FROM
(
select A.First_Name, C.product_quantity * D.Retail_Price AS t  otal_sales_amount From join_demo.customer as A
inner join join_demo.customer_order as B  on A.customer_id = B.customer_id
inner join join_demo.order_details C  on B.order_id = C.order_id
inner join join_demo.product as D  on C.product_id= D.product_id
) E
GROUP BY 1
ORDER BY sub_total_sales_amount DESC  LIMIT 1;

查询 2(有人告诉我这个性能更好):

SELECT A.First_Name,  SUM(C.product_quantity * D.Retail_Price)  AS  sub_total_sales_amount
From join_demo.customer as A
inner join join_demo.customer_order as B  on A.customer_id = B.customer_id
inner join join_demo.order_details C  on B.order_id = C.order_id
inner join join_demo.product as D  on C.product_id= D.product_id  GROUP BY 1
ORDER BY sub_total_sales_amount DESC  LIMIT 1;

我在本地 Mac 上运行 MySQL。但我想这将是一个关于 SQL 性能调整的一般问题。有人可以阐明这个问题吗?非常感激!

更新:感谢@Tim 和@MatBailie。我EXPLAIN在每个查询之前添加。结果完全一样。我猜两个查询的性能水平相同。

ID 选择类型 桌子 分区 类型 可能的键 钥匙 key_len 参考 过滤 额外的
1 简单的 一种 空值 全部 空值 空值 空值 空值 3 100 使用临时的;使用文件排序
1 简单的 空值 全部 空值 空值 空值 空值 4 25 使用哪里;使用连接缓冲区(哈希连接)
1 简单的 C 空值 全部 空值 空值 空值 空值 5 20 使用哪里;使用连接缓冲区(哈希连接)
1 简单的 D 空值 全部 空值 空值 空值 空值 5 20 使用哪里;使用连接缓冲区(哈希连接)

标签: mysqlsqlsql-tuning

解决方案


旧版本的 MySQL 用于自动实现派生表(FROM子句中的子查询)。“Materialize”意味着 MySQL 运行子查询并将结果保存在一个临时位置(在这种情况下,在进行聚合之前)。

我认为从 5.7 版开始优化器得到了改进(尽管历史可能是错误的)。如今,MySQL 在物化方面更加智能,通常会将子查询与外部查询合并。

因此,更新版本的 MySQL 应该产生相同的执行计划。当然,优化器可能会混淆,优化器可能会决定具体化子查询,这在大多数情况下会减慢查询速度。

您可以在文档中阅读有关此内容的更多信息。

您还应该学习使用有意义的表别名,例如cfor customers。并且,限定所有列引用,以便清楚列的来源。任意字母可能比根本没有别名更糟糕(假设列都是合格的)。


推荐阅读