swapping join input

本文探讨了在Oracle数据库中使用SQL查询优化,特别关注了如何通过调整Join操作的顺序来提高查询效率。通过使用特定的HINTs,如`swap_join_inputs`和`leading`,可以改变Join的执行顺序,从而在不同表大小的情况下获得更优的性能。文章还详细解释了如何在查询中使用这些技巧,以实现针对特定场景的最佳查询执行计划。

select * from wxh_tbd1 a ,wxh_tbd2 b where a.id=b.id(+);
对于如上查询,在10G以前,执行计划的结果只可能为(我们只考虑hash join):
-------------------------------------------------------------------------------
| Id  | Operation          | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |          |     1 |   128 |     9  (12)| 00:00:01 |
|*  1 |  HASH JOIN OUTER   |          |     1 |   128 |     9  (12)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| WXH_TBD1 |     1 |    13 |     4   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL| WXH_TBD2 |     1 |   115 |     4   (0)| 00:00:01 |
-------------------------------------------------------------------------------
这样有一个问题,如果wxh_tbd1非常大,而wxh_tbd2非常小,那么我们可能想wxh_tbd2作为build table,这样效率会更高
ORACLE10G后,会根据表大小来自动的完成这种切换
----------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |     1 |   128 |     9  (12)| 00:00:01 |
|*  1 |  HASH JOIN RIGHT OUTER|          |     1 |   128 |     9  (12)| 00:00:01 |
|   2 |   TABLE ACCESS FULL   | WXH_TBD2 |     1 |   115 |     4   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL   | WXH_TBD1 |     1 |    13 |     4   (0)| 00:00:01 |
----------------------------------------------------------------------------------
执行计划显示了一种新的join方式 HASH JOIN RIGHT OUTER

如果我们想改变这种join的顺序,可以通过hint swap_join_inputs来达到目的
select /*+ swap_join_inputs(b) */* from wxh_tbd1 a ,wxh_tbd2 b where a.id=b.id(+);
----------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |     1 |   128 |     9  (12)| 00:00:01 |
|*  1 |  HASH JOIN RIGHT OUTER|          |     1 |   128 |     9  (12)| 00:00:01 |
|   2 |   TABLE ACCESS FULL   | WXH_TBD2 |     1 |   115 |     4   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL   | WXH_TBD1 |     1 |    13 |     4   (0)| 00:00:01 |
----------------------------------------------------------------------------------
 select * from wxh_tbd1 a  where a.object_id in ( select object_id from wxh_tbd2 b);
 ---------------------------------------------------------------------------------
| Id  | Operation            | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |          |   398K|    37M|  3640   (1)| 00:00:44 |
|*  1 |  HASH JOIN RIGHT SEMI|          |   398K|    37M|  3640   (1)| 00:00:44 |
|   2 |   TABLE ACCESS FULL  | WXH_TBD2 | 49838 |   243K|   414   (1)| 00:00:05 |
|   3 |   TABLE ACCESS FULL  | WXH_TBD1 |   398K|    35M|  3222   (1)| 00:00:39 |
---------------------------------------------------------------------------------

select /*+ leading(a) */* from wxh_tbd1 a  where a.object_id in ( select object_id from wxh_tbd2 b);
---------------------------------------------------------------------------------------
| Id  | Operation          | Name     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |          |   398K|    37M|       |  5663   (1)| 00:01:08 |
|*  1 |  HASH JOIN SEMI    |          |   398K|    37M|    39M|  5663   (1)| 00:01:08 |
|   2 |   TABLE ACCESS FULL| WXH_TBD1 |   398K|    35M|       |  3222   (1)| 00:00:39 |
|   3 |   TABLE ACCESS FULL| WXH_TBD2 | 49838 |   243K|       |   414   (1)| 00:00:05 |
---------------------------------------------------------------------------------------
 select * from wxh_tbd2 a where a.object_id in ( select object_id from wxh_tbd1 b);
 ---------------------------------------------------------------------------------------
| Id  | Operation          | Name     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |          | 49663 |  4752K|       |  4208   (1)| 00:00:51 |
|*  1 |  HASH JOIN SEMI    |          | 49663 |  4752K|  5112K|  4208   (1)| 00:00:51 |
|   2 |   TABLE ACCESS FULL| WXH_TBD2 | 49838 |  4526K|       |   415   (1)| 00:00:05 |
|   3 |   TABLE ACCESS FULL| WXH_TBD1 |   398K|  1946K|       |  3215   (1)| 00:00:39 |
---------------------------------------------------------------------------------------

select * from wxh_tbd2 a where a.object_id in ( select /*+ swap_join_inputs(b) */ object_id from wxh_tbd1 b);
-----------------------------------------------------------------------------------------
| Id  | Operation            | Name     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |          | 49663 |  4752K|       |  4207   (1)| 00:00:51 |
|*  1 |  HASH JOIN RIGHT SEMI|          | 49663 |  4752K|  6624K|  4207   (1)| 00:00:51 |
|   2 |   TABLE ACCESS FULL  | WXH_TBD1 |   398K|  1946K|       |  3215   (1)| 00:00:39 |
|   3 |   TABLE ACCESS FULL  | WXH_TBD2 | 49838 |  4526K|       |   415   (1)| 00:00:05 |
-----------------------------------------------------------------------------------------

swap_join_inputs还可以控制hash join的顺序,t1作为build表和T2做hash_join,然后t3作为build表和t1,t2的结果集作hash_join,在把t3,t1,t2的结果集作build表和t4做hash_join
create table t1 as select * from dba_objects;
create table t2 as select * from dba_objects;
create table t3 as select * from dba_objects;
create table t4 as select * from dba_objects;
exec dbms_stats.gather_table_stats(user,'t1');
exec dbms_stats.gather_table_stats(user,'t2');
exec dbms_stats.gather_table_stats(user,'t3');
exec dbms_stats.gather_table_stats(user,'t4');  

select
/*+                            
 ordered                        
 use_hash(t2)                   
 use_hash(t3)                   
 swap_join_inputs(t3)           
 use_hash(t4)                   
 no_swap_join_inputs(t4)        
 */
 *
  from t1, t2, t3, t4
 where t1.object_id = t2.object_id
   and t2.object_name = t3.object_name
   and t3.owner = t4.owner
   and t4.owner = 'MYDB' ;

-------------------------------------------------------------------------------------
| Id  | Operation            | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |     9 |  3348 |       |   431   (1)| 00:00:06 |
|*  1 |  HASH JOIN           |      |     9 |  3348 |       |   431   (1)| 00:00:06 |
|*  2 |   HASH JOIN          |      |     6 |  1674 |       |   373   (1)| 00:00:05 |
|*  3 |    TABLE ACCESS FULL | T3   |     2 |   186 |       |    57   (0)| 00:00:01 |
|*  4 |    HASH JOIN         |      | 19854 |  3606K|  2048K|   315   (1)| 00:00:04 |
|   5 |     TABLE ACCESS FULL| T1   | 19948 |  1811K|       |    58   (2)| 00:00:01 |
|   6 |     TABLE ACCESS FULL| T2   | 19949 |  1811K|       |    58   (2)| 00:00:01 |
|*  7 |   TABLE ACCESS FULL  | T4   |     2 |   186 |       |    57   (0)| 00:00:01 |
------------------------------------------------------------------------------------- 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22034023/viewspace-703293/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/22034023/viewspace-703293/

A-1 Intersection Set of Prime Factors 分数 20 作者 陈越 单位 浙江大学 Given a positive integer n. Select two distinct digits from the decimal repersentation(十进制表示)of n, we obtain another integer m. What is the size of the intersection set(交集)of the prime factors of n and m? For example, given n=623457198, its prime factor set is A = {2, 3, 7, 13, 380621}. Swapping 2 and 9 gives us m=693457128, of which the prime factor set is B = {2, 3, 7, 13, 109, 971}. Then the intersection set of A and B is {2, 3, 7, 13}, with 4 factors. Input Specification: Each input file contains one test case, which gives a positive integer n (10<n≤10 9 ). It is guaranteed that there are at least 2 distinct digits in n. Output Specification: Swap any pair of digits in n to obtain m, you are supposed to find the m with the largest intersection set of the prime factors of n and m. Output in a line the number of the prime factors in the intersection set, together with m. The numbers must be separated by 1 space, and there must be no extra space at the beginning or the end of the line. In case such an m is not unique, output the one with the smallest value. Sample Input: 623457198 Sample Output: 4 123457698 Hint: There are two m's with 4 common factors. Besides the one given in the problem description, we can also swap 6 and 1 to obtain 123457698. This number has a prime factor set {2, 3, 7, 13, 23, 29, 113}, and so the intersection set is also {2, 3, 7, 13}. This number is in the ouput because it is smaller than 693457128.(c++)
最新发布
07-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值