mysql - 这两个 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 | 使用哪里;使用连接缓冲区(哈希连接) |
解决方案
旧版本的 MySQL 用于自动实现派生表(FROM
子句中的子查询)。“Materialize”意味着 MySQL 运行子查询并将结果保存在一个临时位置(在这种情况下,在进行聚合之前)。
我认为从 5.7 版开始优化器得到了改进(尽管历史可能是错误的)。如今,MySQL 在物化方面更加智能,通常会将子查询与外部查询合并。
因此,更新版本的 MySQL 应该产生相同的执行计划。当然,优化器可能会混淆,优化器可能会决定具体化子查询,这在大多数情况下会减慢查询速度。
您可以在文档中阅读有关此内容的更多信息。
您还应该学习使用有意义的表别名,例如c
for customers
。并且,限定所有列引用,以便清楚列的来源。任意字母可能比根本没有别名更糟糕(假设列都是合格的)。
推荐阅读
- c# - 有没有办法使用 RestSharp 仅获取访问令牌?
- chatbot - AIML 用户重复
- git - 无法 git 提交
- javascript - 如何创建变量值数组的变量?
- onelogin - React Native 移动应用 OneLogin 配置
- function - 为什么 GGIR R 代码需要很长时间才能运行?
- python - 如何在 Flask 中的 send_from_directory 之后删除文件?
- python - 我可以使用 python 来简化涉及所有列的 SQLite 查询吗?
- javascript - 连接这两个字符串如何导致这个结果?
- azure - 使用 Azure Pipelines 在虚拟机规模集上进行 Azure Python 函数分解