首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查询的联合本身生成不同的计划。

查询的联合本身生成不同的计划。
EN

Stack Overflow用户
提问于 2012-10-15 13:38:55
回答 2查看 949关注 0票数 6

此查询如下:

查询1:

代码语言:javascript
复制
SELECT * FROM DUAL 

等于并产生与以下相同的结果:

查询2:

代码语言:javascript
复制
SELECT * FROM DUAL 
UNION
SELECT * FROM DUAL

在运行这两个查询之前,这一点是显而易见的。

然而,Oracle似乎不理解这个非常简单的事实,并生成了两个不同的计划:

计划1:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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-ALLSORT UNIQUE操作成本低吗?或者在这两种情况下,是否都有一种方法,一种提示,强迫Oracle生成相同的计划?

谢谢!

更新

Tnoy的回答迫使我做了更多的实验。其结果是:当查询与自身合并时,较大的查询不一定等同于原始查询.

例如,我创建了一个非常简单的test表,该表只有一个列,并且加载了两个相同的行。

现在,我对这个表的第一个查询是:

代码语言:javascript
复制
SELECT * FROM TEST 

返回此结果:

代码语言:javascript
复制
  A
-----
  2
  2

而我的联合编辑的查询:

代码语言:javascript
复制
SELECT * FROM TEST
UNION
SELECT * FROM TEST

返回此结果:

代码语言:javascript
复制
  A
-----
  2

这意味着Oracle优化器正在做正确的事情。

谢谢托尼!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-15 13:48:50

我不是Oracle开发人员,但我猜DB引擎必须“查看”所有行( UNION ALL查询的结果),才能通过执行唯一的排序来计算有多少重复。

在你问题的结尾,你说

...is有一种方法,一种提示,迫使甲骨文在两种情况下生成相同的计划?

我不这么认为,因为您正在尝试执行两个不同的查询。第一个查询是针对“表中的所有行”,第二个查询是询问“表中所有唯一行”,

即使您没有任何副本,数据库也不知道这一点,必须执行排序。

票数 3
EN

Stack Overflow用户

发布于 2012-10-15 14:01:01

对于查看查询的人来说,显而易见的事情对优化器来说并不一定明显。

UNION语句执行一个UNION ALL和一个DISTINCT。虽然数据库优化器可以搜索这个特定的情况(一个在完全相同的表之间进行联合的查询),但是开发人员/管理人员必须就优先级做出决定。

在这种情况下,确定优化可能是非常低的优先级。在您的特定示例中,执行计划可能是不同的,但两者基本上都是即时的(除非您将在一个循环中对数百万个示例执行此操作)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12896838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档