database - Oracle 执行计划改变

标签 database oracle

我有一个问题:

             SELECT COUNT(1)
             FROM registration r,
                  proxy p
             WHERE r.participant_code = p.participant_code
               AND r.proxy_type = p.proxy_type
               AND r.proxy_value = p.proxy_value
               AND r.proxy_sequence= p.proxy_sequence

表“proxy”的连接条件中使用的所有四个字段都在“proxy”主键中。查询的执行计划一直是主键扫描,突然间改成了索引扫描全表扫描。

在该查询稍作更改后(加入 'r.proxy_value = p.proxy_value' 和 'r.proxy_type = p.proxy_type' 交换位置):

             SELECT COUNT(1)
             FROM registration r,
                  proxy p
             WHERE r.participant_code = p.participant_code
               AND r.proxy_value = p.proxy_value                   
               AND r.proxy_type = p.proxy_type
               AND r.proxy_sequence= p.proxy_sequence

实际上这两个查询是等价的。然而,在此更改后,第二个查询的执行计划开始使用索引扫描而不是全扫描。

现在我有一个非常具体的问题:

Oracle 是否会重新编译第二个查询,是否会导致查询执行计划发生变化?

最佳答案

Oracle 现在默认使用基于成本的优化器 (CBO),而以前的基于规则的优化器可预测性更强,但在数据仓库场景中的能力要差得多。

一般来说,CBO 引入了“计划稳定性”问题,而 RBO 的计划始终保持不变。

使用 CBO 意味着执行计划可以并且将会根据统计信息和/或动态采样数据的变化自行更改。实际上有一些工具可以监控计划切换历史(例如 lab128)。

我在查看您的查询时注意到的另一点:没有过滤器,因此根据您的实际主键是什么,索引扫描可能很少使用。

关于database - Oracle 执行计划改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40399339/

相关文章:

php - 数据库存在,但 WordPress 无法建立数据库连接

python - 可以打印或检查有多少数据库连接请求打开以及是否关闭? Django

java - Oracle DB 网络交互速度非常慢

mysql - 是否可以在 IN 子句或任何其他可能的方式中传递两列

SQL查询以获取当前和去年的销售额

mysql - 跨多个数据库共享用户表以实现单次登录

mysql - 将新列添加到整个数据库表

mysql - "leaflet"如何使用 MySQL 数据库存储和检索(搜索)标记?

oracle - 比较SQL Server和Oracle中的表

c# - 从 Oracle 数据库表填充 DataTable - C#