sql - 为什么 oracle 优化器不消除这种情况?
问题描述
我怀疑这个案子,但不清楚为什么。
考虑以下 sql:
create table t1(tid int not null, t1 int not null);
create table t2(t2 int not null, tname varchar(30) null);
create unique index i_t2 on t2(t2);
create or replace view v_1 as
select t1.tid,t1.t1,max(t2.tname) as tname
from t1 left join t2
on t1.t1 = t2.t2
group by t1.tid,t1.t1;
然后检查从 v_1 中选择 count(1) 的执行计划,优化器消除了 t2:
SQL> select count(1) from v_1;
Execution Plan
----------------------------------------------------------
Plan hash value: 3243658773
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 3 (34)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | | |
| 2 | VIEW | VM_NWVW_0 | 1 | | 3 (34)| 00:00:01 |
| 3 | HASH GROUP BY | | 1 | 26 | 3 (34)| 00:00:01 |
| 4 | TABLE ACCESS FULL| T1 | 1 | 26 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------
但是如果索引 i_t2 在没有唯一属性的情况下被删除或重新创建,
执行计划中没有消除表 t2:
SQL> drop index i_t2;
Index dropped.
SQL> select count(1) from v_1;
Execution Plan
----------------------------------------------------------
Plan hash value: 2710188186
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 5 (20)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | | |
| 2 | VIEW | VM_NWVW_0 | 1 | | 5 (20)| 00:00:01 |
| 3 | HASH GROUP BY | | 1 | 39 | 5 (20)| 00:00:01 |
|* 4 | HASH JOIN OUTER | | 1 | 39 | 4 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL| T1 | 1 | 26 | 2 (0)| 00:00:01 |
| 6 | TABLE ACCESS FULL| T2 | 1 | 13 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------------------------
似乎即使删除了索引,
select count(1) from v_1 的结果也等于 select count(1) from (select tid,t1 from t1 group by tid,t1)
为什么优化器在第二种情况下不消除 t2 ?
是否有任何原则或实际数据示例说明这一点?谢谢 :)
解决方案
这是一种称为联接消除的优化。因为 t2.t2 我们是唯一的,优化器知道从 t1 检索的每一行只能从 t2 检索一行。由于 t2 没有投影,因此无需执行连接。如果你这样做
select tid, t1 from v_1;
您会看到我们不执行连接。但是,如果我们从 t2 进行投影,则需要连接。
推荐阅读
- javascript - React Native 声音不工作(远程 URL)
- html - e.preventDefault 会在点击 li 后屏蔽锚标签
- node.js - 如何在 Express js 中使用 multer 将图像上传到 Google Cloud
- python-3.x - 在 python3 中安装库 bls-lib 时出错
- python - Nativescript 找不到六个
- unit-testing - 在单元测试golang之前init函数不运行
- solr - Solr如何使用路径层次标记器在电子商务中实现类别?
- javascript - 为什么我会收到“RangeError:超出最大调用堆栈大小”?
- python - 在嵌套列表中创建随机 ndarray 的优雅方式
- javascript - jquery中根据id获取对象的名字