oracle hint原理

      oracle的hint很多人都知道,那原理是什么呢?在系统中该不该用呢?先来做个试验:

create table test1 as select * from dba_objects where rownum <=100;

create table test2 as select * from dba_objects where rownum <=1000;
alter system flush shared_pool;
alter session set events '10053 trace name context forever, level 1';
select /*+use_nl(t1,t2)*/count(*) from test1 t1,test2 t2 where t1.object_id = t2.object_id;
alter session set events '10053 trace name context off';


trace的结果:
***************************************
OPTIMIZER STATISTICS AND COMPUTATIONS
***************************************
GENERAL PLANS
***************************************
Considering cardinality-based initial join order.
***********************
Join order[1]:  TEST1[T1]#0  TEST2[T2]#1
***************
Now joining: TEST2[T2]#1
***************
NL Join
  Outer table: Card: 100.00  Cost: 3.00  Resp: 3.00  Degree: 1  Bytes: 72
  Inner table: TEST2  Alias: T2
  Access Path: TableScan
    NL Join:  Cost: 311.61  Resp: 311.61  Degree: 0
      Cost_io: 310.00  Cost_cpu: 49756767
      Resp_io: 310.00  Resp_cpu: 49756767
  Best NL cost: 311.61
          resc: 311.61 resc_io: 310.00 resc_cpu: 49756767
          resp: 311.61 resp_io: 310.00 resp_cpu: 49756767
Join Card:  100.00 = outer (100.00) * inner (1000.00) * sel (1.0000e-003)
Join Card - Rounded: 100 Computed: 100.00
Best:: JoinMethod: NestedLoop
       Cost: 311.61  Degree: 1  Resp: 311.61  Card: 100.00  Bytes: 152
***********************
Best so far: Table#: 0  cost: 3.0024  card: 100.0000  bytes: 7200
             Table#: 1  cost: 311.6068  card: 100.0000  bytes: 15200
***********************
Join order[2]:  TEST2[T2]#1  TEST1[T1]#0
***************
Now joining: TEST1[T1]#0
***************
NL Join
  Outer table: Card: 1000.00  Cost: 5.02  Resp: 5.02  Degree: 1  Bytes: 80
  Inner table: TEST1  Alias: T1
  Access Path: TableScan
    NL Join:  Cost: 1026.43  Resp: 1026.43  Degree: 0
      Cost_io: 1024.00  Cost_cpu: 75104022
      Resp_io: 1024.00  Resp_cpu: 75104022
  Best NL cost: 1026.43
          resc: 1026.43 resc_io: 1024.00 resc_cpu: 75104022
          resp: 1026.43 resp_io: 1024.00 resp_cpu: 75104022
Join Card:  100.00 = outer (1000.00) * inner (100.00) * sel (1.0000e-003)
Join Card - Rounded: 100 Computed: 100.00
Join order aborted: cost > best plan cost
***********************
(newjo-stop-1) k:0, spcnt:0, perm:2, maxperm:2000
*********************************
Number of join permutations tried: 2
*********************************
(newjo-save)    [1 0 ]
Final - All Rows Plan:  Best join order: 1
  Cost: 311.6068  Degree: 1  Card: 100.0000  Bytes: 15200
  Resc: 311.6068  Resc_io: 310.0000  Resc_cpu: 49756767
  Resp: 311.6068  Resp_io: 310.0000  Resc_cpu: 49756767
  
        如果不加hint的话,oracle会对比两张表hash join,nested loop,merge join的cost,比较后选择最优,但用了hint后,只会出现nested loop的评估。所以说hint的原理就是给oracle加限制。

        那到底用不用hint呢?短期来说Hint也许是个解决问题的最快方案,但它从长远来看会引入风险。无法保证以后数据分布情况不会变化;无法保证以后表结构不会变化,无法保证以后数据库不会升级。环境一直在变化,只有通过计算出各种执行计划的成本,选择最优的计划,才是最科学的。

        结论是能不用就不用。

你可能感兴趣的:(oracle hint原理)