考虑下列sql
select
/*+
leading(t1 t2 t3 t4)
use_hash(t2) use_hash(t3) use_hash(t4)
*/
count(t1.small_vc),
count(t2.small_vc),
count(t3.small_vc),
count(t4.small_vc)
from
t1,
t2,
t3,
t4
where
t2.id2 = t1.id1
and t3.id3 = t2.id2
and t4.id4 = t3.id3;
You have NOT defined a hash join completely until you have specified which rowsource should be used as the build table and which as the probe table – so every time you supplyy the use_hash() hint for a table, you should also supply the swap_join_inputs() hint or the no_swap_join_inputs() hint.Besides SWAP_JOIN_INPUTS hint only work on hash join
SWAP_JOIN_INPUTS 说明 连接当中谁做内建表
NO_SWAP_JOIN_INPUTS 说它做探测表
So my original query is suffering from incomplete hinting. There are three hash joins, so there should be three hints about swapping inputs or not. For example:
/*+
leading(t1 t2 t3 t4)
use_hash(t2) no_swap_join_inputs(t2)
use_hash(t3) no_swap_join_inputs(t3)
use_hash(t4) no_swap_join_inputs(t4)
*/
Since there are two possibilites for the swap/no_swap option, there are 2 x 2 x 2 = 8 possibilities in total for the execution plan – even though only one join order is examined. (If you check the 10053 trace file for this query you will find all the computation for these execution plans under one line that reads: Join order [1], there will not be a Join order[2])
use_hash(t2) no_swap_join_inputs(t2) use_hash(t3) no_swap_join_inputs(t3) use_hash(t4) no_swap_join_inputs(t4) -------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | -------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 24 | 11 | | 1 | SORT AGGREGATE | | 1 | 24 | | |* 2 | HASH JOIN | | 70 | 1680 | 11 | |* 3 | HASH JOIN | | 70 | 1260 | 8 | |* 4 | HASH JOIN | | 70 | 840 | 5 | | 5 | TABLE ACCESS FULL| T1 | 70 | 420 | 2 | | 6 | TABLE ACCESS FULL| T2 | 70 | 420 | 2 | | 7 | TABLE ACCESS FULL | T3 | 70 | 420 | 2 | | 8 | TABLE ACCESS FULL | T4 | 70 | 420 | 2 | -------------------------------------------------------------- use_hash(t2) swap_join_inputs(t2) use_hash(t3) no_swap_join_inputs(t3) use_hash(t4) no_swap_join_inputs(t4) -------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | -------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 24 | 11 | | 1 | SORT AGGREGATE | | 1 | 24 | | |* 2 | HASH JOIN | | 70 | 1680 | 11 | |* 3 | HASH JOIN | | 70 | 1260 | 8 | |* 4 | HASH JOIN | | 70 | 840 | 5 | | 5 | TABLE ACCESS FULL| T2 | 70 | 420 | 2 | | 6 | TABLE ACCESS FULL| T1 | 70 | 420 | 2 | | 7 | TABLE ACCESS FULL | T3 | 70 | 420 | 2 | | 8 | TABLE ACCESS FULL | T4 | 70 | 420 | 2 | -------------------------------------------------------------- use_hash(t2) no_swap_join_inputs(t2) use_hash(t3) swap_join_inputs(t3) use_hash(t4) no_swap_join_inputs(t4) -------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | -------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 24 | 11 | | 1 | SORT AGGREGATE | | 1 | 24 | | |* 2 | HASH JOIN | | 70 | 1680 | 11 | |* 3 | HASH JOIN | | 70 | 1260 | 8 | | 4 | TABLE ACCESS FULL | T3 | 70 | 420 | 2 | |* 5 | HASH JOIN | | 70 | 840 | 5 | | 6 | TABLE ACCESS FULL| T1 | 70 | 420 | 2 | | 7 | TABLE ACCESS FULL| T2 | 70 | 420 | 2 | | 8 | TABLE ACCESS FULL | T4 | 70 | 420 | 2 | -------------------------------------------------------------- use_hash(t2) swap_join_inputs(t2) use_hash(t3) swap_join_inputs(t3) use_hash(t4) no_swap_join_inputs(t4) -------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | -------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 24 | 11 | | 1 | SORT AGGREGATE | | 1 | 24 | | |* 2 | HASH JOIN | | 70 | 1680 | 11 | |* 3 | HASH JOIN | | 70 | 1260 | 8 | | 4 | TABLE ACCESS FULL | T3 | 70 | 420 | 2 | |* 5 | HASH JOIN | | 70 | 840 | 5 | | 6 | TABLE ACCESS FULL| T2 | 70 | 420 | 2 | | 7 | TABLE ACCESS FULL| T1 | 70 | 420 | 2 | | 8 | TABLE ACCESS FULL | T4 | 70 | 420 | 2 | -------------------------------------------------------------- use_hash(t2) no_swap_join_inputs(t2) use_hash(t3) no_swap_join_inputs(t3) use_hash(t4) swap_join_inputs(t4) -------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | -------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 24 | 11 | | 1 | SORT AGGREGATE | | 1 | 24 | | |* 2 | HASH JOIN | | 70 | 1680 | 11 | | 3 | TABLE ACCESS FULL | T4 | 70 | 420 | 2 | |* 4 | HASH JOIN | | 70 | 1260 | 8 | |* 5 | HASH JOIN | | 70 | 840 | 5 | | 6 | TABLE ACCESS FULL| T1 | 70 | 420 | 2 | | 7 | TABLE ACCESS FULL| T2 | 70 | 420 | 2 | | 8 | TABLE ACCESS FULL | T3 | 70 | 420 | 2 | -------------------------------------------------------------- use_hash(t2) swap_join_inputs(t2) use_hash(t3) no_swap_join_inputs(t3) use_hash(t4) swap_join_inputs(t4) -------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | -------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 24 | 11 | | 1 | SORT AGGREGATE | | 1 | 24 | | |* 2 | HASH JOIN | | 70 | 1680 | 11 | | 3 | TABLE ACCESS FULL | T4 | 70 | 420 | 2 | |* 4 | HASH JOIN | | 70 | 1260 | 8 | |* 5 | HASH JOIN | | 70 | 840 | 5 | | 6 | TABLE ACCESS FULL| T2 | 70 | 420 | 2 | | 7 | TABLE ACCESS FULL| T1 | 70 | 420 | 2 | | 8 | TABLE ACCESS FULL | T3 | 70 | 420 | 2 | -------------------------------------------------------------- use_hash(t2) no_swap_join_inputs(t2) use_hash(t3) swap_join_inputs(t3) use_hash(t4) swap_join_inputs(t4) -------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | -------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 24 | 11 | | 1 | SORT AGGREGATE | | 1 | 24 | | |* 2 | HASH JOIN | | 70 | 1680 | 11 | | 3 | TABLE ACCESS FULL | T4 | 70 | 420 | 2 | |* 4 | HASH JOIN | | 70 | 1260 | 8 | | 5 | TABLE ACCESS FULL | T3 | 70 | 420 | 2 | |* 6 | HASH JOIN | | 70 | 840 | 5 | | 7 | TABLE ACCESS FULL| T1 | 70 | 420 | 2 | | 8 | TABLE ACCESS FULL| T2 | 70 | 420 | 2 | -------------------------------------------------------------- use_hash(t2) swap_join_inputs(t2) use_hash(t3) swap_join_inputs(t3) use_hash(t4) swap_join_inputs(t4) -------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | -------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 24 | 11 | | 1 | SORT AGGREGATE | | 1 | 24 | | |* 2 | HASH JOIN | | 70 | 1680 | 11 | | 3 | TABLE ACCESS FULL | T4 | 70 | 420 | 2 | |* 4 | HASH JOIN | | 70 | 1260 | 8 | | 5 | TABLE ACCESS FULL | T3 | 70 | 420 | 2 | |* 6 | HASH JOIN | | 70 | 840 | 5 | | 7 | TABLE ACCESS FULL| T2 | 70 | 420 | 2 | | 8 | TABLE ACCESS FULL| T1 | 70 | 420 | 2 | --------------------------------------------------------------
Note the extreme change in shape and apparent order of tables in the plan. Despite this the join order really is t1 -> t2 -> t3 -> t4 in every case. I’ll give a quick description of the first and last plans to explain this.
First plan (no_swap all the way):
We build a hash table from t1 and probe it with t2 to create a result set
As this result set is generated we build a new hash table from it
As the result set completes we discard the hash table from t1
We probe the result set with t3 to create a second result set
As the second result set is generated we build a new hash table from it
As the second result set completes we discard the hash table from the first result set
We probe the second result set with t4 to create a third result set
As the third result set is generated we pass the results up to the aggregation step to count the output.
It is very obvious from this description that the tables are being joined in the order we dictated.
Last plan (swap all the way)
We build a hash table from t4
We build a hash table from t3
We build a hash table from t2
We pick a row from t1 and probe the t2 hash,
if the row “survives” we probe the t3 hash
if the row “survives” we probe the t4 hash
if the row “survives” we pass it up to the aggregation step to be counted.
With this description it becomes clear that, once again, the tables are being joined in the order we dictated.
Notice: the number of in-memory hash tables we build in the first case is two and, no matter how many tables are involved in this pattern, the number of in-memory hash tables will always be two.The actual size of the two hash tables is a little unpredictable, though, and, a very crude guideline, you might expect the size to grow as more tables are joined into the result set. In the last case the number of in-memory hash tables we build is “N-1″ (where N is the number of tables joined). We can predict the approximate size of each hash table because it is based on the data we expect to extract from the corresponding “real” table. If you have enough memory to hold all the hash tables in memory at once you will find that this join pattern is likely to be the fastest option you can produce.
Footnote: although a hash join is not fully specified unless you have also supplied an associated “swap/no swap” hint, the no_swap_join_inputs() hint didn’t become available until 10g !
参考至:http://www.cnblogs.com/princessd8251/articles/3535995.html
http://www.cnblogs.com/princessd8251/articles/3535995.html
本文原创,转载请注明出处、作者
如有错误,欢迎指正
邮箱:czmcj@163.com
相关推荐
《Linux交换分析神器:swap_digger及其应用》 在信息技术领域,Linux系统因其稳定性和安全性而备受推崇。然而,随着网络安全问题的日益突出,数据安全和隐私保护成为了至关重要的议题。在这一背景下,"swap_digger...
标题中的"swap_1位swap电路_logisim_swap_"指的是一个关于数字逻辑设计中的1位交换(swap)电路,该电路使用逻辑门实现输入信号的交换功能。在电子工程和计算机科学领域,这样的电路通常用于数据处理或计算过程中...
swap_256Mb.bz2有需要的请下载
标题"swap_state.rar_swap"暗示我们关注的焦点是与交换状态相关的代码或实现,而"swapper_space"则是一个内核中的概念,与这一主题直接相关。 描述中提到的"swapper_space"是一个虚构的概念,它的存在是为了简化...
本文将深入探讨“swap_uchar.zip”文件所涉及的知识点,包括位域赋值和位赋值,以及如何实现一个字节8bit的反转。 首先,让我们了解“位域赋值”。在C语言中,位域允许我们将内存中的特定位范围定义为特定类型的...
"swap_io.rar_swap"这个标题暗示了我们正在讨论与字节交换相关的操作,可能是一个用于处理字节序转换的库或者工具。描述中的“大小字节转换”进一步明确了这一点,它指的是在大端字节序(Big-Endian)和小端字节序...
先使用1位的swap搭建4位的swap,再使用4位的swap模块和Logisim内置的comparator元件搭建排序电路(请不要使用Plexers类元件) 功能描述:该电路具有4个4位的二进制数字作为输入和4个4位的二进制数字作为输出。它的功能...
标题"swap color.rar_dug9ab_swap_swapping与swap"可能指的是一个关于颜色交换的项目,其中可能包含了对背景和前景颜色进行交换的算法或应用。"dug9ab"可能是项目的一个特定标识符,而"swapping与swap"则强调了这个...
formatted_task1151_swap_max_min.json
formatted_task089_swap_words_verification.json
在本项目"Project1_logisim_swap_"中,我们利用Logisim这一强大的逻辑设计工具,实现了基本的SWAP功能。Logisim是一款流行的图形化逻辑设计软件,它提供了一个直观的界面,使用户可以轻松地创建和模拟数字电路。 ...
信息安全_数据安全_Blockchain_Anchored_Swap_Meet_—a_mock_trial 信息保护 可信计算 数据泄露 应急响应 数据泄密
这里我们关注成员函数`swap`的实现,即`2_swap_c++交换函数`所涉及的内容。 在C++中,一个类的`swap`成员函数通常如下所示: ```cpp class MyClass { public: // 其他成员... void swap(MyClass& other) { // ...
在IT行业中,尤其是在C++编程领域,"swap_test.rar_assignment_mv assignment swap"这一标题和描述涉及到的是对象复制和赋值操作的重要概念。标题中的“swap”通常指的是交换两个变量或对象的值,而“assignment”则...
「安全研究」Blockchain_Anchored_Swap_Meet_—a_mock_trial - 技术分析 NGFW 数据安全 安全意识 web安全 安全认证
在描述中提到的三个关键组件——`swap_256Mb`、`fs_512`和`initrd`,都是Linux系统中的核心组成部分: 1. **swap_256Mb**:这是一个交换分区文件,大小为256MB。在Linux系统中,当物理内存不足时,交换分区会作为...
标题“swap_flaskInstagram_python_”暗示我们正在讨论一个与Python相关的项目,它涉及到Flask框架和Instagram API的集成,可能用于用户代码交换或数据迁移。让我们深入探讨这些知识点。 **Flask框架** Flask是一个...
资源分类:Python库 所属语言:Python 资源全名:swap_python_sdk-0.1.9-py3.8.egg 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
标题"swap_string.cpp.zip_swap"暗示这是一个关于C++中字符串交换的程序,可能使用了某种特殊的交换方法,如zip交换,这可能是对两个字符串逐个字符交换的过程。描述"c++ programming swap string"进一步确认了我们...