当前位置:操作系统 > Unix/Linux >>

CBO学习之一What do you mean by Cost

CBO学习之一What do you mean by Cost
 
Mr. Lewis代码如下,注释部分略作改动:
 
[sql] 
/*  
Script:     first_rows.sql  
Author:     Jonathan Lewis  
Dated:      June 2002  
Purpose:    Problems with FIRST_ROWS optimisation  
  
Last tested   
    10.1.0.4  
     9.2.0.6  
     8.1.7.4  
  
The FIRST_ROWS optimizer does not have a sensible strategy  
for dealing with optimisation of an ORDER BY (and possibly  
other variants such as GROUP BY) when it finds it can use  
an index to do the ORDER BY "free of charge".  
  
This example demonstrates the point. Without the in-line  
view, Oracle does a full scan on the primary key index to  
return the 100 required rows in order, at a total cost  
and total execution time that is much higher than that of  
using the required index.  
  
Of course, it is arguably the case that this is correct  
behaviour if we assume that the time to the first row is  
important, and therefore we avoid collecting a large number  
of rows and sorting them.  In practice, this is perhaps not  
really likely to be the case.  
  
Bug number 670328 applies  
  
Parameter _sort_elimination_cost_ratio affects the break  
point between optimising for the WHERE clause and optimising  
for the ORDER BY clause.  
  
If the parameter is zero, the ORDER BY clause takes precedence  
If the parameter is non-zero, then the index is used if the cost   
of using it is less than the cost of doing the sort multiplied   
by the value of the parameter.  
  
Special note for 10g:  
The parameter still has the same effect in general, but zero  
now means zero, not (effectively) infinity.  The default of  
zero will now effectively ignore the index option unless it  
is actually cheaper than the non-index option. A non-zero  
value will behave as it always used to  
*/  
  
--start setenv  
  
drop table t1;  
  
begin  
    begin       execute immediate 'purge recyclebin';  
    exception   when others then null;  
    end;  
  
    begin       execute immediate 'begin dbms_stats.delete_system_stats; end;';  
    exception   when others then null;  
    end;  
  
    begin       execute immediate 'alter session set "_optimizer_cost_model"=io';  
    exception   when others then null;  
    end;  
  
end;  
/  
  
create table t1 as  
select  
    rownum          id,  
--  mod(rownum,100)     modded,  
    mod(rownum,300)     modded,  
    lpad(rownum,1000)   padding  
from  
    all_objects  
where  
    rownum <= 10000  
;  
  
alter table t1 add constraint t1_pk primary key(id);  
create index t1_mod on t1(modded);  
  
begin  
    dbms_stats.gather_table_stats(  
        user,  
        't1',  
        cascade => true,  
        estimate_percent => null,  
        method_opt => 'for all columns size 1'  
    );  
end;  
/  
  
alter session set optimizer_mode=first_rows;  
  
set autotrace traceonly explain  
  
spool first_rows  
  
/*  
Get a base-line cost and plan for acquiring the rows  
*/  
  
select  *  
from    t1  
where   modded = 0  
;  
  
/*  
See what happens if we add an 'order by primary key'.  
*/  
  
select  *  
from    t1  
where   modded = 0  
order by   
    id  
;  
  
/*  
Block the PK index from being used for ordering, and see  
that Oracle could notionally get a better path. Strangely  
the cost varies depending on the strategy used for blocking  
the index. On my 9.2.0.6 test, the no_merge hint managed to  
reduce the lengths of the rows to be sorted, and therefore  
calculated a smaller cost.  
*/  
  
/*  
Block the index with a no_merge hint  
*/  
  
select * from (  
select  /*+ no_merge */   
    *  
from    t1  
where   modded = 0  
)  
order by   
    id  
;  
  
  
/*  
Block the index with a no_index hint  
*/  
  
select  /*+ no_index(t1,t1_pk) */  
    *  
from    t1  
where   modded = 0  
order by   
    id  
;  
  
set autotrace off  
  
/*  
The costs under 8i are:  
    Using the PK index to avoid the sort:       1,450  
    Block the PK index (no_index) and sorting:  43  
  
Cost ratio: 1450/43 = 33.729, so we test   
    _sort_elimination_cost_ratio at 33 and 34  
  
At 33:  43 * 33 = 1,419:  so the PK nosort should be ignored  
At 34:  43 * 34 = 1,462:  so the PK nosort falls inside the limit.  
  
(Because of a change in the cost in 10g, t
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,