Bel*_*Bob 18 mysql performance oracle
这两个示例查询之间是否存在性能差异?
查询 1:
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
where b.tag = 'Y'
Run Code Online (Sandbox Code Playgroud)
查询 2;
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
and b.tag = 'Y'
Run Code Online (Sandbox Code Playgroud)
注意唯一的区别是补充条件的位置;第一个使用WHERE子句,第二个将条件添加到ON子句中。
当我在 Teradata 系统上运行这些查询时,解释计划是相同的,JOIN 步骤显示了每种情况下的附加条件。但是,在关于 MySQL 的这个 SO 问题上,其中一个答案表明首选第二种样式,因为WHERE在进行连接之后进行处理。
编码这样的查询时是否有一般规则要遵循?我猜它必须依赖于平台,因为它显然对我的数据库没有影响,但这也许只是 Teradata 的一个功能。而如果它是与平台相关的,我非常喜欢弄几个文件的参考资料; 我真的不知道该找什么。
Rol*_*DBA 14
根据Sasha Pachev的《Understanding MySQL Internals》一书第 9 章(解析器和优化器)第 172 页

以下是将查询评估分解为以下任务:
ORDER BY和GROUP BY。在同一页面上,它说:
在 MySQL 优化器术语中,每个查询都是一组连接。术语连接在这里比 SQL 命令中使用的更广泛。只有一个表的查询是退化连接。虽然我们通常不认为从一张表中读取记录是一种连接,但与传统连接使用的相同结构和算法可以完美地解决只有一张表的查询。
由于存在的键、数据量和查询的表达方式,MySQL Joins 有时可能会为我们自己(或报复我们)做一些事情,并得出我们没有预料到且无法快速解释的结果。
我之前写过关于这种怪癖的文章
Jan 23, 2013:嵌套更新查询的问题Feb 22, 2011: MySQL 子查询的问题因为 MySQL 查询优化器可以在查询评估期间关闭某些键。
@Phil 的评论帮助我了解如何发布此答案(@Phil 的评论为 +1)
@ypercube 的评论(这个评论也是 +1)是我帖子的精简版,因为 MySQL 的查询优化器是原始的。不幸的是,它必须是因为它处理外部存储引擎。
至于您的实际问题,MySQL Query Optimizer 将在完成每个查询时确定其性能指标
您可能必须通过重写(重构)查询来强制执行顺序
这是您提供的第一个查询
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
where b.tag = 'Y';
Run Code Online (Sandbox Code Playgroud)
尝试重写它以首先评估 WHERE
select count(*)
from table1 a
join (select key_col from table2 where tag='Y') b
on b.key_col=a.key_col;
Run Code Online (Sandbox Code Playgroud)
那肯定会改变解释计划。它可能会产生更好或更坏的结果。
我曾经在 StackOverflow 中回答过一个问题,我在那里应用了这种技术。解释是可怕的,但表现是炸药。它只是因为存在正确的索引并且在子查询中使用了 LIMIT 才起作用。
与股票价格一样,当涉及到查询并试图表达它们时,会受到限制,结果可能会有所不同,而且过去的表现并不代表未来的结果。
| 归档时间: |
|
| 查看次数: |
7208 次 |
| 最近记录: |