*************************************************************
t1表有100行记录
t2表有1M行记录
t1表T1"."N" 有索引
t2表T2"."T1_ID"有索引
=------正确执行计划应该为:
SQL_ID cgwuncwm2pryk, child number 0
-------------------------------------
SELECT * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n <= 19
Plan hash value: 2669480776
-------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
-------------------------------------------------------------------------------------------------------------
| 1 | TABLE ACCESS BY INDEX ROWID | T2 | 1 | 1 | 19 |00:00:00.01 | 49 | 3 |
| 2 | NESTED LOOPS | | 1 | 24 | 39 |00:00:00.01 | 30 | 0 |
| 3 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 24 | 19 |00:00:00.01 | 6 | 0 |
|* 4 | INDEX RANGE SCAN | T1_N | 1 | 24 | 19 |00:00:00.01 | 3 | 0 |
|* 5 | INDEX RANGE SCAN | T2_T1_ID | 19 | 1 | 19 |00:00:00.01 | 24 | 0 |
-------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("T1"."N"<=19)
5 - access("T1"."ID"="T2"."T1_ID")
22 rows selected.
----手工设置表的统计信息,使oracle cbo 误认为t2为小表,t1 为大表
EXEC dbms_stats.SET_table_stats(user, 'T1', numrows => 200000000 ,numblks => 1000000);
EXEC dbms_stats.SET_table_stats(user, 'T2', numrows => 1 ,numblks => 1);
*************************************************************
----这里只添加一行使用T2"."T1_ID 的索引的大纲hint
SQL_ID gjdju6xucw779, child number 0
-------------------------------------
SELECT /*+ INDEX(@"SEL$1" "T2"@"SEL$1" ("T2"."T1_ID")) */ * FROM t1, t2 WHERE t1.id
=t2.t1_id AND t1.n <= 19
Plan hash value: 2481503312
----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------------
|* 1 | TABLE ACCESS BY INDEX ROWID | T1 | 1 | 49 | 19 |00:00:57.44 | 100K|
| 2 | NESTED LOOPS | | 1 | 49 | 2000K|00:00:39.16 | 100K|
| 3 | TABLE ACCESS BY INDEX ROWID| T2 | 1 | 1 | 100K|00:00:02.70 | 100K|
| 4 | INDEX FULL SCAN | T2_T1_ID | 1 | 1 | 100K|00:00:00.66 | 225 |
|* 5 | INDEX RANGE SCAN | T1_N | 100K| 100 | 1900K|00:00:13.51 | 5 |
----------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1 / T1@SEL$1
3 - SEL$1 / T2@SEL$1
4 - SEL$1 / T2@SEL$1
5 - SEL$1 / T1@SEL$1
Outline Data
-------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('10.2.0.1')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "T2"@"SEL$1" ("T2"."T1_ID"))
INDEX(@"SEL$1" "T1"@"SEL$1" ("T1"."N"))
LEADING(@"SEL$1" "T2"@"SEL$1" "T1"@"SEL$1")
USE_NL(@"SEL$1" "T1"@"SEL$1")
END_OUTLINE_DATA
*/
Predicate Information (identified by operation id):
--------------------------------------------------
1 - filter("T1"."ID"="T2"."T1_ID")
5 - access("T1"."N"<=19)
47 rows selected.
SQL>
***********************************************
***********************************************
----通过修改大纲hint信息来影响执行计划,这里添加了t2 表的索引hint, t1作为驱动表的hint,使用nl 的hint
SELECT
/*+
INDEX(@"SEL$1" "T2"@"SEL$1" ("T2"."T1_ID"))
LEADING(@"SEL$1" "T1"@"SEL$1" "T2"@"SEL$1")
USE_NL(@"SEL$1" "T2"@"SEL$1")
*/ *
FROM t1, t2 WHERE t1.id=t2.t1_id AND t1.n <= 19;
SQL_ID 0106c7pwnv5hh, child number 0
-------------------------------------
SELECT /*+ INDEX(@"SEL$1" "T2"@"SEL$1" ("T2"."T1_ID")) LEADING(@"SEL$1" "T1"@"SEL$1"
"T2"@"SEL$1") USE_NL(@"SEL$1" "T2"@"SEL$1") */ * FROM t1, t2 WHERE t1.id=t2.t1_id AND t1.n
<= 19
Plan hash value: 2669480776
----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------------
| 1 | TABLE ACCESS BY INDEX ROWID | T2 | 1 | 1 | 19 |00:00:00.01 | 49 |
| 2 | NESTED LOOPS | | 1 | 49 | 39 |00:00:00.01 | 30 |
| 3 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 4800K| 19 |00:00:00.01 | 6 |
|* 4 | INDEX RANGE SCAN | T1_N | 1 | 100 | 19 |00:00:00.01 | 3 |
|* 5 | INDEX RANGE SCAN | T2_T1_ID | 19 | 1 | 19 |00:00:00.01 | 24 |
----------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1 / T2@SEL$1
3 - SEL$1 / T1@SEL$1
4 - SEL$1 / T1@SEL$1
5 - SEL$1 / T2@SEL$1
Outline Data
-------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('10.2.0.1')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "T1"@"SEL$1" ("T1"."N"))
INDEX(@"SEL$1" "T2"@"SEL$1" ("T2"."T1_ID"))
LEADING(@"SEL$1" "T1"@"SEL$1" "T2"@"SEL$1")
USE_NL(@"SEL$1" "T2"@"SEL$1")
END_OUTLINE_DATA
*/
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("T1"."N"<=19)
5 - access("T1"."ID"="T2"."T1_ID")
48 rows selected.
*************************************************************
-----只是用nl 小表驱动hint:
SQL_ID bannu3t7caycc, child number 0
-------------------------------------
SELECT /*+ leading(t1) use_nl(t2) */ * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n <= 19
Plan hash value: 76617097
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
--------------------------------------------------------------------------------------------------------
| 1 | NESTED LOOPS | | 1 | 49 | 19 |00:00:00.07 | 18723 | 983 |
| 2 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 4800K| 19 |00:00:00.01 | 6 | 2 |
|* 3 | INDEX RANGE SCAN | T1_N | 1 | 100 | 19 |00:00:00.01 | 3 | 1 |
|* 4 | TABLE ACCESS FULL | T2 | 19 | 1 | 19 |00:00:00.07 | 18717 | 981 |
--------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
2 - SEL$1 / T1@SEL$1
3 - SEL$1 / T1@SEL$1
4 - SEL$1 / T2@SEL$1
Outline Data
-------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('10.2.0.1')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "T1"@"SEL$1" ("T1"."N"))
FULL(@"SEL$1" "T2"@"SEL$1")
LEADING(@"SEL$1" "T1"@"SEL$1" "T2"@"SEL$1")
USE_NL(@"SEL$1" "T2"@"SEL$1")
END_OUTLINE_DATA
*/
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("T1"."N"<=19)
4 - filter("T1"."ID"="T2"."T1_ID")
45 rows selected.
!!!!!但是("T2"."T1_ID") 表上的索引 T2_T1_ID 还是用没有被oracle的optimize 优化器采用(为什么没有自动使用没有想明白?)
*******************************************************
----添加索引 nl 的hint:
SQL_ID 300a951pfx6vn, child number 0
-------------------------------------
SELECT /*+ leading(t1) use_nl(t2) index(t2 T2_T1_ID) */ * FROM t1, t2 WHERE t1.id = t2.t1_id AND
t1.n <= 19
Plan hash value: 266948077
-------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
-------------------------------------------------------------------------------------------------------------
| 1 | TABLE ACCESS BY INDEX ROWID | T2 | 1 | 1 | 19 |00:00:00.01 | 49 | 2 |
| 2 | NESTED LOOPS | | 1 | 49 | 39 |00:00:00.01 | 30 | 2 |
| 3 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 4800K| 19 |00:00:00.01 | 6 | 0 |
|* 4 | INDEX RANGE SCAN | T1_N | 1 | 100 | 19 |00:00:00.01 | 3 | 0 |
|* 5 | INDEX RANGE SCAN | T2_T1_ID | 19 | 1 | 19 |00:00:00.01 | 24 | 2 |
-------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1 / T2@SEL$1
3 - SEL$1 / T1@SEL$1
4 - SEL$1 / T1@SEL$1
5 - SEL$1 / T2@SEL$1
Outline Data
-------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('10.2.0.1')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "T1"@"SEL$1" ("T1"."N"))
INDEX(@"SEL$1" "T2"@"SEL$1" ("T2"."T1_ID"))
LEADING(@"SEL$1" "T1"@"SEL$1" "T2"@"SEL$1")
USE_NL(@"SEL$1" "T2"@"SEL$1")
END_OUTLINE_DATA
*/
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("T1"."N"<=19)
5 - access("T1"."ID"="T2"."T1_ID")
47 rows selected.
---------关于大纲hint 的信息简化写法
INDEX
语法:INDEX([<@查询块>] <表> [<索引>]) 或者 INDEX([<@查询块>] <表> [(<索引字段列表>)])
描述:指示优化器通过索引来访问和扫描表。
SQL_ID 2uc505kd7jsj8, child number 0
-------------------------------------
SELECT /*+
INDEX(T2(T2.T1_ID)) ------索引的hint也可以这么写
LEADING(T1 T2)
USE_NL(T2)
*/ * FROM t1, t2 WHERE t1.id=t2.t1_id AND t1.n <= 19
Plan hash value: 2669480776
----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------------
| 1 | TABLE ACCESS BY INDEX ROWID | T2 | 1 | 1 | 19 |00:00:00.01 | 49 |
| 2 | NESTED LOOPS | | 1 | 49 | 39 |00:00:00.01 | 30 |
| 3 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 4800K| 19 |00:00:00.01 | 6 |
|* 4 | INDEX RANGE SCAN | T1_N | 1 | 100 | 19 |00:00:00.01 | 3 |
|* 5 | INDEX RANGE SCAN | T2_T1_ID | 19 | 1 | 19 |00:00:00.01 | 24 |
----------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1 / T2@SEL$1
3 - SEL$1 / T1@SEL$1
4 - SEL$1 / T1@SEL$1
5 - SEL$1 / T2@SEL$1
Outline Data
------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('10.2.0.1')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "T1"@"SEL$1" ("T1"."N"))
INDEX(@"SEL$1" "T2"@"SEL$1" ("T2"."T1_ID"))
LEADING(@"SEL$1" "T1"@"SEL$1" "T2"@"SEL$1")
USE_NL(@"SEL$1" "T2"@"SEL$1")
END_OUTLINE_DATA
*/
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("T1"."N"<=19)
5 - access("T1"."ID"="T2"."T1_ID")
47 rows selected.
SQL>
SQL_ID 2qz4v29ugrh94, child number 0
-------------------------------------
SELECT /*+ INDEX(T2) LEADING(T1 T2) USE_NL(T2) */ * FROM t1, t2 WHERE t1.id=t2.t1_id AND
t1.n <= 19
Plan hash value: 2669480776
----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------------
| 1 | TABLE ACCESS BY INDEX ROWID | T2 | 1 | 1 | 19 |00:00:00.01 | 49 |
| 2 | NESTED LOOPS | | 1 | 49 | 39 |00:00:00.01 | 30 |
| 3 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 4800K| 19 |00:00:00.01 | 6 |
|* 4 | INDEX RANGE SCAN | T1_N | 1 | 100 | 19 |00:00:00.01 | 3 |
|* 5 | INDEX RANGE SCAN | T2_T1_ID | 19 | 1 | 19 |00:00:00.01 | 24 |
----------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1 / T2@SEL$1
3 - SEL$1 / T1@SEL$1
4 - SEL$1 / T1@SEL$1
5 - SEL$1 / T2@SEL$1
Outline Data
-------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('10.2.0.1')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "T1"@"SEL$1" ("T1"."N"))
INDEX(@"SEL$1" "T2"@"SEL$1" ("T2"."T1_ID"))
LEADING(@"SEL$1" "T1"@"SEL$1" "T2"@"SEL$1")
USE_NL(@"SEL$1" "T2"@"SEL$1")
END_OUTLINE_DATA
*/
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("T1"."N"<=19)
5 - access("T1"."ID"="T2"."T1_ID")
47 rows selected.
SQL>