【原創】ORACLE 資料分析和動態取樣
《ORACLE 資料分析和動態取樣》
引言:oracle 資料庫效能調優最需要重視的也最常遇到的就是SQL執行效率,而反映SQL效率最直觀的工具就是CBO生成的執行計劃,那麼如何讓CBO生成最精準的效率最高的執行計劃成為我們當前需要研究的課題。同一條語句,好的執行計劃能帶來飛一樣的速度,壞的執行計劃讓我們痛苦不堪,下面我們從原理到實踐來把如何產生高效計劃的方法教給大家。
一 CBO介紹
CBO全稱叫Cost Based optimization基於代價最佳化器,它是一個數學模型,同一個SQL語句在不同的oracle版本中計算出來的代價結果也是不一樣的,因為每個版本CBO最佳化器的設計結構有很大不同,現在還不是很完善很智慧很通人性,因此我們不能完全依賴它,只能輔助我們。
如何生成精確的執行計劃:公式資料+CBO=執行計劃,傳入CBO的資料越精確得到結果越精確,我們能做的保證輸入資料更準確,透過精確資料計算出精確執行計劃
二演示一個表分析後執行計劃比動態取樣更準確的例子
動態取樣:顧名思義就是oracle自動為你進行的初步資料分析,由於是隨機在表上取一些資料,因此並不能保證得出的執行計劃很準確,只能作為一種輔助分析手段,在不得已的情況下來分析資料,有一定的侷限性。
場景:當表沒有分析資訊時,oracle會使用動態取樣技術,而且動態取樣是在SQL硬解析的時候發生的,傳入->CBO引數->生成執行計劃。
級別:oracle 10g oracle 11g 預設動態取樣級別是2,它有level1-10,設定的級別越高採集的資料塊越多,結果越精確,執行時間越長,level10對所有資料進行取樣分析。
實驗
LEO1@LEO1> drop table leo1 purge;清理環境
Table dropped.
LEO1@LEO1> drop table leo2 purge;
Table dropped.
LEO1@LEO1> create table leo1 as select * from dba_objects;建立leo1表
Table created.
LEO1@LEO1> create table leo2 as select * from leo1;建立leo2表,採用leo1一樣資料和結構
Table created.
LEO1@LEO1> col segment_name for a10
LEO1@LEO1> select segment_name,extents,blocks from dba_segments where segment_name in ('LEO1','LEO2');
SEGMENT_NA EXTENTS BLOCKS
---------- ---------- -------------- -------------- ----
LEO1 24 1152
LEO2 24 1152
查詢leo1和leo2表這兩個段物件儲存引數,都是佔用24個區,1152個塊,2個表一模一樣嘛
LEO1@LEO1> col table_name for a10
LEO1@LEO1> select table_name,num_rows,blocks,status from dba_tables wheretable_name in ('LEO1','LEO2');
TABLE_NAME NUM_ROWS BLOCKS STATUS
---------- ---------- ---------- ------------ ---------- ------------
LEO1 VALID
LEO2 VALID
在這個資料字典裡只顯示錶名和當前狀態(有效),沒有行資訊和塊資訊,這是為神馬呢,嗯從上面的操作可以看出,我們只是建立了表,但沒有分析表統計資訊,現在我們分析一下後看看效果
LEO1@LEO1> execute dbms_stats.gather_table_stats('LEO1','LEO1');對LEO1表進行統計分析
PL/SQL procedure successfully completed.
LEO1@LEO1> select table_name,num_rows,blocks,status from dba_tables wheretable_name in ('LEO1','LEO2');
TABLE_NAME NUM_ROWS BLOCKS STATUS
---------- ---------- ---------- ------------ ---------- ------------
LEO1 71968 1051 VALID
LEO2 VALID
現在leo1表已經有行資訊和塊資訊了,leo2由於沒有進行表分析現在還什麼都沒有
LEO1@LEO1> set autotrace trace exp
LEO1@LEO1> select * from leo1 where object_id=10000;
Execution Plan
----------------------------------------------------------
Plan hash value: 2716644435
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 97 | 287 (1)| 00:00:04 |
|* 1 | TABLE ACCESS FULL| LEO1 | 1 | 97 | 287 (1)| 00:00:04 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OBJECT_ID"=10000)
Leo1表進行了統計分析,執行計劃顯示Rows=1,嗯由於object_id欄位是不重複的,我們都知道object_id=10000只有一條記錄,這和執行計劃的判斷結果是一致,所以表分析可以讓oracle收集表資料的資訊,讓CBO瞭解表資料分佈情況,有多少條,佔用多少空間等。
總之“分析”就是讓oracle理解我們的資料是怎麼樣一個情況,以便更好的去處理它
LEO1@LEO1> select * from leo2 where object_id=10000;
Execution Plan
----------------------------------------------------------
Plan hash value: 2258638698
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 12 | 2484 | 287 (1)| 00:00:04 |
|* 1 | TABLE ACCESS FULL| LEO2 | 12 | 2484 | 287 (1)| 00:00:04 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OBJECT_ID"=10000)
Note
-----
- dynamic sampling used for this statement (level=2)
Leo2表沒有進行統計分析,oracle採用了動態取樣技術(紅色字顯示),執行計劃顯示Rows=12,由於動態取樣只是隨機在表上取一些資料來評估,沒有進行全表完整分析,固然得出的執行計劃沒有leo1表更精確更好。所以說“動態取樣”只是一個補救措施。
三演示在缺乏直方圖(柱狀圖)時,CBO計算出錯誤的執行計劃的例子,並給出最後正確的執行計劃
直方圖(柱狀圖):oracle對列上的資料分佈情況進行統計,得出的圖示。
場合:常用於檢視資料傾斜情況(一個值在整個欄位中所佔比例),瞭解某個鍵值所擁有的記錄數
如果是數字1這個鍵值在整個欄位中佔用的比例
如果是字元leonarding這個鍵值在整個欄位中佔用的比例
如果是日期 2012-12-21 這個日期在整個欄位中佔用的比例
直方圖型別:
(1)Frequency-頻率直方圖:用於基數少,記錄多,重複率高的欄位
(2)Height Balanced-高度平衡直方圖:用於基數多,唯一值多,重複率低的欄位,這個就是等分相同資料量的桶(bucket),值可能不同,來顯示桶中記錄數的比例
實驗
LEO1@LEO1> drop table leo3 purge;清除環境
Table dropped.
LEO1@LEO1> drop table leo4 purge;
Table dropped.
LEO1@LEO1> create table leo3 as select * from dba_objects;建立leo3表
Table created.
LEO1@LEO1> create table leo4 as select * from dba_objects;建立leo4表
Table created.
LEO1@LEO1> execute dbms_stats.gather_table_stats('LEO1','LEO3',method_opt=>'for all columns size 1');
PL/SQL procedure successfully completed.
LEO1@LEO1> execute dbms_stats.gather_table_stats('LEO1','LEO4',method_opt=>'for all columns size 254');
PL/SQL procedure successfully completed.
對leo3表做資訊收集但沒有做直方圖分析(for all columns size 1)1 代表不做直方圖
對leo4表做資訊收集但又做了直方圖分析(for all columns size 254)254 代表最精確直方圖對所有列都做分析,在分析表時把更多資料告訴CBO,得出最精確的執行計劃。
注:刪除表上分析資訊語句
LEO1@LEO1> execute dbms_stats.delete_table_stats('LEO1','LEO3');
PL/SQL procedure successfully completed.
LEO1@LEO1> select table_name,column_name,num_distinct,num_buckets,histogram from dba_tab_col_statistics where table_name in ('LEO3','LEO4');
TABLE_NAME COLUMN_NAME NUM_DISTINCT NUM_BUCKETS HISTOGRAM
---------- ------------------------------ ------------ ----------- ---------------
LEO3 EDITION_NAME 0 0 NONE
LEO3 NAMESPACE 20 1 NONE
LEO3 SECONDARY 2 1 NONE
LEO3 GENERATED 2 1 NONE
LEO3 TEMPORARY 2 1 NONE
LEO3 STATUS 2 1 NONE
LEO3 TIMESTAMP 1227 1 NONE
LEO3 LAST_DDL_TIME 1170 1 NONE
LEO3 CREATED 1097 1 NONE
LEO3 OBJECT_TYPE 43 1 NONE
LEO3 DATA_OBJECT_ID 7262 1 NONE
LEO3 OBJECT_ID 71966 1 NONE
LEO3 SUBOBJECT_NAME 58 1 NONE
LEO3 OBJECT_NAME 43424 1 NONE
LEO3 OWNER 24 1 NONE
LEO4 EDITION_NAME 0 0 NONE
LEO4 NAMESPACE 20 14 FREQUENCY
LEO4 SECONDARY 2 2 FREQUENCY
LEO4 GENERATED 2 2 FREQUENCY
LEO4 TEMPORARY 2 2 FREQUENCY
LEO4 STATUS 2 1 FREQUENCY
LEO4 TIMESTAMP 1228 254 HEIGHT BALANCED
LEO4 LAST_DDL_TIME 1171 254 HEIGHT BALANCED
LEO4 CREATED 1098 254 HEIGHT BALANCED
LEO4 OBJECT_TYPE 43 30 FREQUENCY
LEO4 DATA_OBJECT_ID 7263 254 HEIGHT BALANCED
LEO4 OBJECT_ID 71967 254 HEIGHT BALANCED
LEO4 SUBOBJECT_NAME 58 58 FREQUENCY
LEO4 OBJECT_NAME 43424 254 HEIGHT BALANCED
LEO4 OWNER 24 19 FREQUENCY
30 rows selected.
引數說明:
TABLE_NAME:表名 leo3我們沒有做直方圖分析顯示NONE 而leo4做了
COLUMN_NAME:列名
NUM_DISTINCT:列中不同鍵值數(就是我們所說基數)
NUM_BUCKETS:直方圖的桶數,用幾個桶來裝資料
HISTOGRAM:直方圖型別,FREQUENCY and HEIGHT BALANCED
例對於status列由於基數少重複率很高則使用frequency直方圖
對於object_id由於都是唯一值沒有重複率則使用height balance直方圖
與我們上面寫的情況一致
LEO1@LEO1> select count(*) from leo3 where object_type='TABLE';標準記錄數2816
COUNT(*)
-----------------
2816
LEO1@LEO1> select count(*) from leo3 where object_type='TABLE';
Execution Plan
----------------------------------------------------------
Plan hash value: 3505406240
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 9 | 287 (1)| 00:00:04 |
| 1 | SORT AGGREGATE | | 1 | 9 | | |
|* 2 | TABLE ACCESS FULL| LEO3 | 1674 | 15066 | 287 (1)| 00:00:04 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("OBJECT_TYPE"='TABLE')
由於leo3我們沒有做直方圖分析,CBO就不知道object_type='TABLE'在整個欄位中所佔比例,導致Rows=1674與標準2816偏差太大,這就是沒有足夠分析資料的結果
LEO1@LEO1> select count(*) from leo4 where object_type='TABLE';
Execution Plan
----------------------------------------------------------
Plan hash value: 3210696650
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 9 | 287 (1)| 00:00:04 |
| 1 | SORT AGGREGATE | | 1 | 9 | | |
|* 2 | TABLE ACCESS FULL| LEO4 | 2697 | 24273 | 287 (1)| 00:00:04 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("OBJECT_TYPE"='TABLE')
由於leo4做了全表整體直方圖分析,生成254個桶來裝資料,oracle必然瞭解object_type='TABLE'在整個欄位中所佔比例,Rows=2697 和標準2816 已經非常接近了,相對比較精確,這就是有足夠分析資料的結果。
四演示在分割槽表上,全域性資訊和分割槽資訊是如何影響執行計劃的,給出演示過程
全域性統計資訊:如果跨分割槽CBO使用全域性統計資訊
分割槽統計資訊:如果不跨分割槽CBO使用分割槽統計資訊
全域性資訊和分割槽資訊是2個獨立資訊源,某些情況下會有聯絡
實驗
LEO1@LEO1> drop table leo5 purge;清除環境
Table dropped.
LEO1@LEO1> drop table leo6 purge;
Table dropped.
LEO1@LEO1> create table leo5建立一個分割槽表
partition by range (object_id)
(
partition p1 values less than(10000),
partition p2 values less than(20000),
partition p3 values less than(30000),
partition p4 values less than(40000),
partition p5 values less than(50000),
partition p6 values less than(60000),
partition pm values less than(maxvalue)
) as select * from dba_objects; 2 3 4 5 6 7 8 9 10 11
Table created.
LEO1@LEO1> execute dbms_stats.gather_table_stats('LEO1','LEO5');預設對全域性和分割槽都做分析
PL/SQL procedure successfully completed.
LEO1@LEO1> select table_name,num_rows,blocks,global_stats from dba_tables where table_name in ('LEO5');
TABLE_NAME NUM_ROWS BLOCKS GLO
---------- ---------- ---------- ----- ---------- ---------- ------------ ------
LEO5 71979 1111 YES
從全域性上看,Leo5表有71979行記錄佔用1111個塊
LEO1@LEO1> select table_name,partition_name,num_rows,blocks,global_stats from dba_tab_partitionswhere table_name='LEO5';
TABLE_NAME PARTITION_NAME NUM_ROWS BLOCKS GLO
---------- ------------------------------ ---------- ---------- ---
LEO5 P1 9708 137 YES
LEO5 P2 9806 152 YES
LEO5 P3 10000 158 YES
LEO5 P4 10000 159 YES
LEO5 P5 10000 159 YES
LEO5 P6 9606 150 YES
LEO5 PM 12859 196 YES
從分割槽上看,每個分割槽有多少行記錄佔用了多少個資料塊,總和應該與全域性資訊一致
NUM_ROWS:是一個估算值
LEO1@LEO1> execute dbms_stats.gather_table_stats('LEO1','LEO5',granularity=>'partition');
PL/SQL procedure successfully completed.
Granularity引數:針對分割槽表來說的,在哪個粒度上做分析
Global:全域性級別分析
Partition:分割槽級別分析
Subpartition:子分割槽級別分析
我們這條命令單獨對分割槽做分析,更新分割槽統計資訊,不更新全域性統計資訊
LEO1@LEO1> select table_name,num_rows,blocks,global_stats from dba_tables where table_name in ('LEO5');
TABLE_NAME NUM_ROWS BLOCKS GLO
---------- ---------- ---------- ------------ ---------- ---------------
LEO5 71979 1111 YES
全域性統計資訊沒有變化,與實際資料資訊不相符了
LEO1@LEO1> select table_name,partition_name,num_rows,blocks,global_stats from dba_tab_partitions where table_name='LEO5';
TABLE_NAME PARTITION_NAME NUM_ROWS BLOCKS GLO
---------- ------------------------------ ---------- ---------- ---
LEO5 P1 19416 382 YES
LEO5 P2 19612 382 YES
LEO5 P3 20000 382 YES
LEO5 P4 20000 382 YES
LEO5 P5 20000 382 YES
LEO5 P6 19212 382 YES
LEO5 PM 25718 382 YES
分割槽統計資訊已經被更新了
現在看一下統計資訊是如何被使用的
LEO1@LEO1> select count(*) from leo5 where object_id<8000;符合條件有15668行
COUNT(*)
------------------
15668
LEO1@LEO1> select count(*) from leo5 where object_id<8000;
Execution Plan
----------------------------------------------------------
Plan hash value: 546738359
------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 4 |105 (0)| 00:00:02 | | |
| 1 | SORT AGGREGATE | | 1| 4 | | | | |
| 2 | PARTITION RANGE SINGLE| | 15534 | 62136 | 105 (0)| 00:00:02 | 1 | 1 |
|* 3 | TABLE ACCESS FULL | LEO5 | 15534 | 62136 | 105 (0)| 00:00:02 | 1 | 1 |
------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("OBJECT_ID"<8000)
由於我們在分割槽級別重新進行了分析,分割槽統計資訊是最新版,CBO使用了最新分割槽統計資訊後Rows=15534 與實際15668 已經相差無疑,基本上得出的是正確結果。
原理:我們說過如果不跨分割槽CBO使用分割槽統計資訊,針對某個分割槽oracle獲取資訊
Pstart| Pstop起始分割槽和結束分割槽都是1,說明結果集都落在了第一個分割槽只需掃描第一個分割槽即可
LEO1@LEO1> select count(*) from leo5 where object_id<30001;符合條件有59030行
COUNT(*)
----------------
59030
LEO1@LEO1> select count(*) from leo5 where object_id<30001;
Execution Plan
----------------------------------------------------------
Plan hash value: 3650668575
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 416 (1)| 00:00:05 | | |
| 1 | SORT AGGREGATE | | 1 | 5 | | | | |
| 2 | PARTITION RANGE ITERATOR| | 29209 | 142K| 416 (1)| 00:00:05 | 1 | 4 |
|* 3 | TABLE ACCESS FULL | LEO5 | 29209 | 142K| 416 (1)| 00:00:05 | 1 | 4 |
--------------------------------------------------------------------------------------------------
跨4個分割槽掃描
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("OBJECT_ID"<30001)
LEO1@LEO1> select count(*) from leo5 where object_id<30000;
Execution Plan
----------------------------------------------------------
Plan hash value: 3650668575
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 313 (1)| 00:00:04 | | |
| 1 | SORT AGGREGATE | | 1 | 5 | | | | |
| 2 | PARTITION RANGE ITERATOR| | 29208 | 142K| 313 (1)| 00:00:04 | 1 | 3 |
| 3 | TABLE ACCESS FULL | LEO5 | 29208 | 142K| 313 (1)| 00:00:04 | 1 | 3 |
--------------------------------------------------------------------------------------------------
跨3個分割槽掃描
小結:只要跨分割槽CBO就使用全域性統計資訊,由於全域性資訊過舊,不管掃描3個分割槽還是4個分割槽Rows=29209 這與實際值59030都相差甚遠,這就是為什麼分割槽裡資料是準的,而全域性裡資料是不準的。
我們再一次對全域性級別分析一次看看全域性統計資訊是不是更新了,執行計劃是不是精準了
LEO1@LEO1> execute dbms_stats.gather_table_stats('LEO1','LEO5',granularity=>'global');
PL/SQL procedure successfully completed.
LEO1@LEO1> select table_name,num_rows,blocks,global_stats from dba_tables where table_name in ('LEO5');
TABLE_NAME NUM_ROWS BLOCKS GLO
---------- ---------- ---------- ------ ---------- ---------- --------
LEO5 143958 2674 YES
這次全域性統計資訊更新了
LEO1@LEO1> select count(*) from leo5 where object_id<30001;
Execution Plan
----------------------------------------------------------
Plan hash value: 3650668575
--------------------------------------------------------------------------------------------------
|Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 416 (1)| 00:00:05 | | |
| 1 | SORT AGGREGATE | | 1 | 5 | | | | |
| 2 | PARTITION RANGE ITERATOR| | 58418 | 285K| 416 (1)| 00:00:05 | 1 | 4 |
|* 3 | TABLE ACCESS FULL | LEO5 | 58418 | 285K| 416 (1)| 00:00:05 | 1 | 4 |
--------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("OBJECT_ID"<30001)
小結:我們使用更新後的全域性統計資訊得出Rows=58418 與實際值59030差不多了,說明單獨對分割槽分析,不會更新全域性統計資訊。
五演示用extended statistics 解決列相關性的例子,給出演示過程
列的相關性:就是where子句中同時存在2個列以上條件時,CBO不做列與列之間相關性分析,這會導致CBO計算執行計劃出現一種偏差
實驗
由於oracle11g之前 CBO不做列與列之間相關性分析,我的實驗環境是11g的沒有10g環境,我們就用其他方式模擬一下吧。
LEO1@LEO1> select count(*) from leo6 where object_type='TABLE' and wner='LEO1';
COUNT(*)
------------------
20符合條件有20行
LEO1@LEO1> select count(*) from leo6 where object_type='TABLE' and wner='LEO1';
Execution Plan
----------------------------------------------------------
Plan hash value: 3995977415
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 28 | 287 (1)| 00:00:04 |
| 1 | SORT AGGREGATE | | 1 | 28 | | |
|* 2 | TABLE ACCESS FULL| LEO6 | 8 | 224 | 287 (1)| 00:00:04 |
---------------------------------------------------------------------------
CBO不做列與列之間相關性分析前提下,Rows=8顯然CBO計算錯誤,應該有20行的
LEO1@LEO1>
executedbms_stats.gather_table_stats('LEO1','LEO6',method_opt=>'for columns (object_type,owner) size skewonly');
PL/SQL procedure successfully completed.
我們對leo6表做列相關性分析,看看CBO計算是否準確
LEO1@LEO1> select count(*) from leo6 where object_type='TABLE' and wner='SYS';
COUNT(*)
----------------
969符合條件有969行
LEO1@LEO1> select count(*) from leo6 where object_type='TABLE' and wner='SYS';
Execution Plan
----------------------------------------------------------
Plan hash value: 3995977415
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 28 | 287 (1)| 00:00:04 |
| 1 | SORT AGGREGATE | | 1 | 28 | | |
|* 2 | TABLE ACCESS FULL| LEO6 | 819 | 22932 | 287 (1)| 00:00:04 |
---------------------------------------------------------------------------
小結:這次CBO的Rows=819與實際值969非常接近了,可以看出作完列與列相關性分析後,CBO知道2個列的資料分佈情況是一個什麼樣子了,從而在計算執行計劃上有更多資料參考得出結果更準確。
六對一張表進行匯出/匯入,看它的統計資訊是否發生改變,給出演示過程。
LEO1@LEO1> drop table leo7 purge;清除環境
Table dropped.
LEO1@LEO1> create table leo7 as select * from dba_objects;建立leo7表
Table created.
LEO1@LEO1> execute dbms_stats.gather_table_stats('LEO1','LEO7');進行表分析
PL/SQL procedure successfully completed.
LEO1@LEO1> select count(*) from leo7;現在我們表裡有71979行記錄
COUNT(*)
-----------------
71979
LEO1@LEO1> select table_name,num_rows,blocks,global_stats from dba_tables where table_name in ('LEO7');
TABLE_NAME NUM_ROWS BLOCKS GLO
---------- ---------- ---------- ---- ---------- ----------- -----
LEO7 71979 1051 YES
做完表分析後,統計資訊已經有了,有71979行,1051個塊,只包括資料段
LEO1@LEO1> select segment_name,extents,blocks from dba_segmentswhere segment_name in ('LEO7');
SEGMENT_NA EXTENTS BLOCKS
---------- ---------- ----------- ---------- -----------
LEO7 24 1152
這是leo7段物件的儲存引數,佔用24個區1152個資料塊,段物件裡面的塊數包括資料段+表頭段的資訊
[oracle@leonarding1 ~]$ expuserid=leo1/leo1@leo1 file=/home/oracle/leo7_dump_file1.dmp tables=leo7 rows=y
Export: Release 11.2.0.1.0 - Production on Sun Jan 20 14:16:45 2013
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Export done in US7ASCII character set and AL16UTF16 NCHAR character set
server uses ZHS16GBK character set (possible charset conversion)
About to export specified tables via Conventional Path ...
. . exporting table LEO7 71979 rows exported
EXP-00091: Exporting questionable statistics.
Export terminated successfully with warnings.
匯出leo7表進行匯出
[oracle@leonarding1 ~]$ ll
total 8208
drwxrwxrwx 8 oracle oinstall 4096 Aug 21 2009 database
drwxr-xr-x 2 oracle oinstall 4096 Nov 17 14:48 Desktop
-rw-r--r-- 1 oracle oinstall 7 Nov 17 15:43 em
-rw-r--r-- 1 oracle oinstall 8314880 Jan 20 14:16 leo7_dump_file1.dmp
-rw-r--r-- 1 oracle oinstall 42201 Dec 16 21:25 orahdfs-1.0.0.0.0.zip
-rwxrwxrwx 1 oracle oinstall 795 Dec 16 23:53 test1.txt
-rwxrwxrwx 1 oracle oinstall 13325 Dec 27 23:13 test.txt
看一下統計資訊,現在沒有變化,也就是說匯出不會更新表統計資訊
LEO1@LEO1> select table_name,num_rows,blocks,global_stats from dba_tables where table_name in ('LEO7');
TABLE_NAME NUM_ROWS BLOCKS GLO
---------- ---------- ---------- ---
LEO7 71979 1051 YES
我們把leo7_dump_file1.dmp在匯入到leo7表中
[oracle@leonarding1 ~]$ imp userid=leo1/leo1@leo1 file=/home/oracle/leo7_dump_file1.dmp full=y ignore=y
Import: Release 11.2.0.1.0 - Production on Sun Jan 20 14:31:12 2013
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Export file created by EXPORT:V11.02.00 via conventional path
import done in US7ASCII character set and AL16UTF16 NCHAR character set
import server uses ZHS16GBK character set (possible charset conversion)
. importing LEO1's objects into LEO1
. importing LEO1's objects into LEO1
. . importing table "LEO7" 71979 rows imported
Import terminated successfully without warnings.
LEO1@LEO1> select count(*) from leo7;
COUNT(*)
----------------
143958
預設追加方式匯入資料,原來71979行,匯入後143958行
LEO1@LEO1> select table_name,num_rows,blocks,global_stats from dba_tables where table_name in ('LEO7');
TABLE_NAME NUM_ROWS BLOCKS GLO
---------- ---------- ---------- ---------- ---------- ----------
LEO7 71979 1051 YES
我們對leo7表進行了追加匯入,但是它的統計資訊還是原來收集的統計資訊,也就是說匯入也不會更新表統計資訊
LEO1@LEO1> execute dbms_stats.gather_table_stats('LEO1','LEO7');
PL/SQL procedure successfully completed.
LEO1@LEO1> select table_name,num_rows,blocks,global_stats from dba_tables where table_name in ('LEO7');
TABLE_NAME NUM_ROWS BLOCKS GLO
---------- ---------- ---------- ---
LEO7 143958 2160 YES
小結:只有重新進行表分析才能更新表統計資訊
動態取樣 直方圖 CBO gather granularity extendedstatisticsexp imp 列相關性
2013.1.20
天津&winter
分享技術~成就夢想
Blog:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14710393/viewspace-1249904/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle動態取樣分析Oracle
- Oracle 分析及動態取樣Oracle
- Oracle 執行計劃 分析和動態取樣Oracle
- Oracle 分析及動態取樣(轉帖)Oracle
- Oracle 動態取樣Oracle
- Oracle動態取樣學習Oracle
- 【原創】Oracle的動態監聽註冊Oracle
- [原創] Oracle資料庫資源管理Oracle資料庫
- 【原創】手工建立Oracle資料庫Oracle資料庫
- 動態sql和利用動態sql解決資料字典的讀取SQL
- oracle動態取樣_optimizer_dynamic_samplingOracle
- Oracle資料庫開發指南(原創)Oracle資料庫
- 【sql調優】動態取樣SQL
- oracle動態取樣_optimizer_dynamic_sampling(二)Oracle
- sql profile禁用oracle動態取樣dynamic samplingSQLOracle
- 原創 oracle 資料完整性總結Oracle
- 【原創】Oracle 資料結構知多少(二)Oracle資料結構
- 【原創】Oracle 資料結構知多少(一)Oracle資料結構
- 【原創】Oracle RAC故障分析與處理Oracle
- CBO與動態統計量取樣
- oracle 啟動篇總結(原創)Oracle
- 運維開發裡的資料動態獲取和自動補錄運維
- 大資料行業現狀分析和最新行業動態大資料行業
- 【原創】Oracle RAC原理和安裝Oracle
- 【原創】oracle spfile和pfile小結Oracle
- 原創:oracle data block 內部結構分析OracleBloC
- 如何找出使用動態取樣的SQLSQL
- 【原創】說說你是如何理解Oracle資料庫中latch和enqueue lock的?Oracle資料庫ENQ
- 【原創】Linux PCI驅動框架分析(一)Linux框架
- 【原創】Linux PCI驅動框架分析(二)Linux框架
- 資料分析:什麼樣性格的創始人容易成功?
- 【原創】MySQL和PostgreSQL 匯入資料對比 薦MySql
- [原創]兩個樣本分析,兩種程式注入學習
- oracle動態取樣dynamic sampling hint為何不生效一點思考Oracle
- 對於沒有任何統計資訊的表,ORACLE可能會動態取樣。Oracle
- [原創] 大資料測試大資料
- 【原創】Oracle execute plan 原理分析與例項分享Oracle
- 如何檢視哪些SQL使用了動態取樣?SQL