cbo心得(選擇率,基數,直方圖)(二)

jlttt發表於2008-08-10
cbo心得(選擇率,基數,直方圖)(二)[@more@]

三,正文

1, 沒有任何統計資訊(包括表,索引,直方圖等)

ORACLE 10g中,RBO已經徹底的被拋棄了,取而代之的是CBO。我們知道CBO的基礎就是統計資訊,那麼在10g中如果沒有收集統計資訊,CBO是怎麼工作的呢?我們看下面的這個例子。


Create table sunwg (Id number);

Create index ind_sunwg on sunwg(id);

Begin

For I in 1..100 loop

For j in 1..i loop

Insert into sunwg values (i);

End loop;

End loop;

Commit;

End;

這樣我們就建立了一張有5050條記錄的測試表。

例1, 不存在統計資訊

SQL> select * from sunwg where id = 10;

已選擇10行。

執行計劃

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

Plan hash value: 3109917279

---------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

---------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 10 | 130 | 1 (0)| 00:00:01 |* 1 | INDEX RANGE SCAN | IND_SUNWG | 10 | 130 | 1 (0)| 00:00:01 ---------------------------------------------------------------------------

Predicate Information (identified by operation id):

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

1 - access("ID"=10)

Note

-----

- dynamic sampling used for this statement

統計資訊

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

9 recursive calls

0 db block gets

25 consistent gets

0 physical reads

124 redo size

478 bytes sent via SQL*Net to client

385 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

10 rows processed

我們可以注意到Note中的說明dynamic sampling used for this statement,這表示在執行上面的SQL的時候,系統對錶和索引進行了動態的取樣。也就是說在執行這個SQL之前系統首先動態的收集表上和索引上的統計資訊,然後利用這些統計資訊透過CBO來找到合適的執行計劃。這個統計的資訊獲得是需要很大的系統開銷的,所以我們一定要把統計資訊的收集放到一個重要的地位。那麼這個收集後的統計資訊會資料庫儲存起來供其他的SQL使用麼?

如果這個統計資訊被資料庫儲存起來的話,那麼其他關於SUNWG表的查詢也會利用到這些統計資訊;反過來說,如果其他SQL沒有使用統計資訊的話,說明這些統計資訊並沒有被儲存起來。

SQL> select * from sunwg where id = 50;

已選擇50行。

執行計劃

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

Plan hash value: 3109917279

-----------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes|Cost (%CPU)| Time |

-----------------------------------------------------------------------| 0 | SELECT STATEMENT | | 50 | 650 | 1 (0)| 00:00:01 |

|* 1 | INDEX RANGE SCAN| IND_SUNWG| 50 | 650 | 1 (0)| 00:00:01 -----------------------------------------------------------------------

Predicate Information (identified by operation id):

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

1 - access("ID"=50)

Note

-----

- dynamic sampling used for this statement

統計資訊

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

7 recursive calls

0 db block gets

26 consistent gets

0 physical reads

0 redo size

1059 bytes sent via SQL*Net to client

418 bytes received via SQL*Net from client

5 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

50 rows processed

我們換了一個查詢,可以看到這次仍然進行了動態的取樣操作,由此可以證明這些統計資訊並沒有被ORACLE儲存起來,對於沒有統計資訊的表每一個相關的查詢都會進行動態的統計資訊的收集。我也查詢了大部分和統計資訊相關的系統表,並沒有發現這些統計資訊,看來這些統計資訊是和特定SQL關聯的,並不會為其他的SQL使用。沒有統計資訊的後果是多麼的可怕啊,本來3個邏輯讀可以搞定的事情,卻用了26個邏輯讀才完成。

那麼這個25個邏輯讀到底讀取了哪些內容呢,下面做個大概的測試。

SQL> analyze table sunwg compute statistics for table for all indexes;

表已分析。

SQL> select blocks,empty_blocks from user_tables;

BLOCKS EMPTY_BLOCKS

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

13 3

SQL> select leaf_blocks from user_indexes;

LEAF_BLOCKS

-----------

9

13 + 9 + 3 = 25

雖然可能不那麼準確,也可以看得出來在進行動態統計資訊收集的時候會對錶和表上索引進行統計,浪費大量的IO,這種浪費並不是僅僅出現一次,在以後的每次查詢的時候會存在的,直到你開始收集統計資訊為止。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9533994/viewspace-1008778/,如需轉載,請註明出處,否則將追究法律責任。

相關文章