多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 數據庫 > 數據庫應用 > 如何獲得正確的基數估計值

如何獲得正確的基數估計值

來源:程序員人生   發布時間:2015-01-04 09:09:14 閱讀次數:4332次
原文:http://www.oracle.com/technetwork/issue-archive/2013/13-jan/o13asktom⑴886639.html


I have a question about joining with collections and cardinality estimation. The optimizer is always estimating that 8,168 rows are coming back from my collection, and because of that, it is using inefficient plans. The estimate of 8,168 is more than two orders of magnitude more than the real cardinality. How can I solve this problem?
我有1個關于集合和基數估計。優化器針對我的集合基數估計總是8168,就由于這,它老師使用低效力計劃。8168是實際基數的2個數量級!
我該如何解決這個問題?


This is a long-running issue with pipelined functions and collections during optimization. The optimizer in general doesn’t have any information about the cardinality (the number of rows) being returned by the collection. It has to guess―and that guess is based on the block size (default statistics are block-size-driven). So, for a database with an 8 K block size, the guess is about 8,000. And because it is unlikely that your collection has about 8,000 elements (probably more like 8 or 80 in most cases), you can definitely arrive at a suboptimal plan.
這的確是個長時間提出的問題:關于管道函數和集合的優化。優化器通常對集合的基數信息毫無所知。它必須去猜!怎樣猜?是基于塊大小。
所以,對8k大小數據塊的數據庫,猜出來的基數就是8000左右!但是通常集合的基數其實不是8000,其更多是8或80。


下面,我提供4種方法來取得正確的集合基數:
1)The cardinality hint (undocumented) 基數提示(無文件證明)


2)The OPT_ESTIMATE hint (undocumented) OPT_ESTIMATE提示(無文件證明)


3)Dynamic sampling (Oracle Database 11g Release 1 and later) 動態采樣(Oracle 11g初版或更高)


4)Oracle Database’s Cardinality Feedback feature (Oracle Database 11g Release 2 and later) Oracle基數反饋特性(Oracle 11g第2版或更高)






-⑴)用于字符串分割的管道函數
SQL> create or replace type str2tblType as table of varchar2(30)
/
Type created. 


SQL> create or replace
function str2tbl( p_str in varchar2, p_delim in varchar2 default ',' )
return str2tblType
PIPELINED
as
    l_str      long default p_str || p_delim;
    l_n        number;
begin
    loop
        l_n := instr( l_str, p_delim );
        exit when (nvl(l_n,0) = 0);
        pipe row( ltrim(rtrim(substr(l_str,1,l_n⑴))) );
        l_str := substr( l_str, l_n+1 );
    end loop;
end;
/
Function created.


SQL> variable x varchar2(15)


SQL> exec :x := '1,2,3,a,b,c'


PL/SQL procedure successfully completed.


SQL> select * from table(str2tbl(:x));


COLUMN_VALUE
――――――――――――――――――――――――――――――――――――――
1
2
3
a
b
c


6 rows selected.


SQL> select * from table(dbms_xplan.display_cursor);


PLAN_TABLE_OUTPUT
――――――――――――――――――――――――――――――――――――――――――――――――――――――――
SQL_ID  ddk1tv9s5pzq5, child number 0
――――――――――――――――――――――――――――――――――――――――――――――――――――――――
select * from table(str2tbl(:x))


Plan hash value: 2407808827


―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
|Id|Operation                      |Name   |Rows|Bytes|Cost (%CPU)|Time    |
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
| 0|SELECT STATEMENT               |       |    |     |  29  (100)|        |
| 1| COLLECTION ITERATOR PICKLER...|STR2TBL|8168|16336|  29    (0)|00:00:01|


--使用CARDINALITY 提示
SQL> select * from table(dbms_xplan.display_cursor);


PLAN_TABLE_OUTPUT
――――――――――――――――――――――――――――――――――――――――――――――――――――――――
SQL_ID  bd2f8rh30z3ww, child number 0
――――――――――――――――――――――――――――――――――――――――――――――――――――――――
select /*+ cardinality(sq 10) */ * from table(str2tbl(:x)) sq


Plan hash value: 2407808827


―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
|Id|Operation                      |Name   |Rows|Bytes|Cost (%CPU)|Time    |
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
| 0|SELECT STATEMENT               |       |    |     |  29  (100)|        |
| 1| COLLECTION ITERATOR PICKLER...|STR2TBL|  10|   20|  29    (0)|00:00:01|


--這地方,我們給優化器提示1個10使其認為管道函數的結果基數為10


-⑵)使用OPT_ESTIMATE提示
--提供3個參數:對象類型;對象名;1個縮放因素,優化器將拿它認為的基數乘以這個因素
--所以,先算出這個大概的因素
SQL> select 10/8168 from dual;


    10/8168
――――――――――――――――
  .00122429


select /*+ opt_estimate(table, sq, scale_rows=0.00122429) */ * 
  from table(str2tbl(:x)) sq


Plan hash value: 2407808827


―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
|Id|Operation                      |Name   |Rows|Bytes|Cost (%CPU)|Time    |
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
| 0|SELECT STATEMENT               |       |    |     |  29  (100)|        |
| 1|  OLLECTION ITERATOR PICKLER...|STR2TBL|  10|   20|  29    (0)|00:00:01|




-⑶)使用DYNAMIC SAMPLING 提示
select /*+ dynamic_sampling( sq, 2 ) */ * from table( str2tbl(:x,',') ) sq


Plan hash value: 2407808827


―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
|Id|Operation                      |Name   |Rows|Bytes|Cost (%CPU)|Time    |
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
| 0|SELECT STATEMENT               |       |    |     |  11  (100)|        |
| 1| COLLECTION ITERATOR PICKLER...|STR2TBL|   6|   12|  11    (0)|00:00:01|
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――


Note
―――――――
dynamic sampling used for this statement (level=2)


-⑷)使用Cardinality Feedback
--這地方我們要將查詢變1下形:
with sq 
as (
select /*+ materialize */ *    
  from table( str2tbl( :x ) )

select * 
  from sq


Plan hash value: 630596523


―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
|Id|Operation                        |Name   |Rows|Bytes|Cost (%CPU)|Time    |
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
| 0|SELECT STATEMENT                 |       |    |     |  32  (100)|        |
| 1| TEMP TABLE TRANSFORMATION       |       |    |     |           |        |
| 2|  LOAD AS SELECT                 |       |    |     |           |        |
| 3|   COLLECTION ITERATOR PICKLER...|STR2TBL|8168|16336|   29   (0)|00:00:01|
| 4|  VIEW                           |       |8168| 135K|    3   (0)|00:00:01|
| 5|   TABLE ACCESS FULL             |SYS_...|8168|16336|    3   (0)|00:00:01|
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――


18 rows selected.


--whoop,第1次還沒生效呢,沒關系, one more try
with sq as (select /*+ materialize */ *    from table( str2tbl( :x ) )
) select * from sq


Plan hash value: 630596523


―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
|Id|Operation                        |Name   |Rows|Bytes|Cost (%CPU)|Time    |
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
| 0|SELECT STATEMENT                         |    |     |  32  (100)|        |
| 1| TEMP TABLE TRANSFORMATION               |    |     |           |        |
| 2|  LOAD AS SELECT                         |    |     |           |        |
| 3|   COLLECTION ITERATOR PICKLER...|STR2TBL|8168|16336|  29    (0)|00:00:01|
| 4|  VIEW                                   |   6| 102 |   3    (0)|00:00:01|
| 5|   TABLE ACCESS FULL             |SYS_...|   6|   12|   3    (0)|00:00:01|
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――


Note
―――――――
   - cardinality feedback used for this statement


22 rows selected.




--這1次OK了
--揭曉1下基數反饋的原理,下面直接援用TOM的話:
Cardinality Feedback works by having the optimizer change its cardinality estimates after executing a query for the first time and observing that the actual cardinalities were very far off from the estimated cardinalities. That is, the optimizer starts to learn from its mistakes. If it executes a query and discovers that the real row counts are far off from the estimated counts, it will reoptimize the query, using the newly discovered values.


關于基數反饋請參考:http://www.oracle.com/technetwork/issue-archive/2010/10-sep/o50asktom⑴65477.html


--------------------------------

Dylan    Presents.

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 免费簧网站永久在线播放国产 | 亚洲另类春色校园小说 | 欧美精品综合一区二区三区 | 俺去久久 | 欧美精品国产精品 | 中文字幕人成不卡一区 | 性欧美video高清熟睡 | 国产成人a| 77777_亚洲午夜久久多人 | 免费视频观看在线www日本 | 男女男精品视频站 | 久久99爱爱| 国产精品免费麻豆入口 | 久久成人精品免费播放 | 国产精品一区二区久久精品 | 女人18毛毛片一级毛片 | 亚洲精品国产福利一区二区三区 | 男人都懂的www网站免费观看 | 国产青草亚洲香蕉精品久久 | 亚洲欧美在线视频免费 | 日本特黄高清免费大片爽 | 欧美亚洲天堂网 | tubexxxxhd日本 | 欧美亚洲日本一区二区三区浪人 | 视频国产一区 | 日本高清在线观看视频www | 宅男午夜大片啪啪软件 | 国产成人一区二区在线不卡 | 国产精品久久久久久久久久一区 | 最近最新高清中文字幕6页 最近最新免费中文字幕8 | 在线天堂在线 | 中文精品久久久久中文 | 国产在线观看第一页 | 91真人毛片一级在线播放 | 又粗又硬又黄又爽的免费视频 | 亚洲永久| 国产精品视频第一页 | 亚洲成人三级 | 国产成人精品免费大全 | 亚洲a影院 | 欧美成视频一theporn |