此查询如下:
查询1:
SELECT * FROM DUAL 等于并产生与以下相同的结果:
查询2:
SELECT * FROM DUAL
UNION
SELECT * FROM DUAL在运行这两个查询之前,这一点是显而易见的。
然而,Oracle似乎不理解这个非常简单的事实,并生成了两个不同的计划:
计划1:
Execution Plan
----------------------------------------------------------
Plan hash value: 272002086
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| DUAL | 1 | 2 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------计划2:
Execution Plan
----------------------------------------------------------
Plan hash value: 646475286
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 4 | 6 (67)| 00:00:01 |
| 1 | SORT UNIQUE | | 2 | 4 | 6 (67)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
| 3 | TABLE ACCESS FULL| DUAL | 1 | 2 | 2 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL| DUAL | 1 | 2 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------为什么会这样呢?简单地比较两个UNION-ed块不是比同时执行UNION-ALL和SORT UNIQUE操作成本低吗?或者在这两种情况下,是否都有一种方法,一种提示,强迫Oracle生成相同的计划?
谢谢!
更新
Tnoy的回答迫使我做了更多的实验。其结果是:当查询与自身合并时,较大的查询不一定等同于原始查询.
例如,我创建了一个非常简单的test表,该表只有一个列,并且加载了两个相同的行。
现在,我对这个表的第一个查询是:
SELECT * FROM TEST 返回此结果:
A
-----
2
2而我的联合编辑的查询:
SELECT * FROM TEST
UNION
SELECT * FROM TEST返回此结果:
A
-----
2这意味着Oracle优化器正在做正确的事情。
谢谢托尼!
发布于 2012-10-15 13:48:50
我不是Oracle开发人员,但我猜DB引擎必须“查看”所有行( UNION ALL查询的结果),才能通过执行唯一的排序来计算有多少重复。
在你问题的结尾,你说
...is有一种方法,一种提示,迫使甲骨文在两种情况下生成相同的计划?
我不这么认为,因为您正在尝试执行两个不同的查询。第一个查询是针对“表中的所有行”,第二个查询是询问“表中所有唯一行”,
即使您没有任何副本,数据库也不知道这一点,必须执行排序。
发布于 2012-10-15 14:01:01
对于查看查询的人来说,显而易见的事情对优化器来说并不一定明显。
UNION语句执行一个UNION ALL和一个DISTINCT。虽然数据库优化器可以搜索这个特定的情况(一个在完全相同的表之间进行联合的查询),但是开发人员/管理人员必须就优先级做出决定。
在这种情况下,确定优化可能是非常低的优先级。在您的特定示例中,执行计划可能是不同的,但两者基本上都是即时的(除非您将在一个循环中对数百万个示例执行此操作)。
https://stackoverflow.com/questions/12896838
复制相似问题