db file sequential read wait event等待事件之二
db file sequential read在什麼情況下會產生
1,rowid定位記錄
2,index scan
3,讀取控制檔案
4,讀取檔案頭
db file sequential read產生過高的原因:
1,選擇不佳的索引
2, 行連結或行遷移
3, buffer cache過小
4, 統計資訊不準
5, binding peek導致執行計劃不準,配置_optim_peek_user_binds=false,禁用binding peek
---建立測試表並構建索引且插入大量資料
SQL> show user
USER is "TBL_BCK"
SQL> create table t_index(a int);
Table created.
SQL> create index idx_t_index on t_index(a);
Index created.
SQL> insert into t_index select object_id from dba_objects;
69780 rows created.
SQL> commit;
Commit complete.
SQL> select count(a),count(distinct a) from t_index;
COUNT(A) COUNT(DISTINCTA)
---------- ----------------
69779 69779
SQL> select index_name,clustering_factor from user_indexes where index_name='IDX
_T_INDEX';
INDEX_NAME CLUSTERING_FACTOR
------------------------------------------------------------ -----------------
IDX_T_INDEX 0
SQL> exec dbms_stats.gather_table_stats(user,'t_index',cascade=>true);
PL/SQL procedure successfully completed.
---收集統計資訊後檢視索引的clustering_factor
SQL> select index_name,clustering_factor from user_indexes where index_name='IDX
_T_INDEX';
INDEX_NAME CLUSTERING_FACTOR
------------------------------------------------------------ -----------------
IDX_T_INDEX 108
---發現index的clustering_factor大小與表的block數量相同
SQL> select count(distinct dbms_rowid.rowid_block_number(rowid)) as block_counts from t_index;
BLOCK_COUNTS
------------
106
SQL> delete from t_index where rownum<=2000;
2000 rows deleted
SQL> commit;
Commit complete
SQL> exec dbms_stats.gather_table_stats(user,'t_index',cascade=>true);
PL/SQL procedure successfully completed
--刪除表記錄後索引的clustering_factor會減少
SQL> select index_name,clustering_factor from user_indexes where index_name='IDX_T_INDEX';
INDEX_NAME CLUSTERING_FACTOR
------------------------------ -----------------
IDX_T_INDEX 105
SQL> insert into t_index select level+300000 from dual connect by level<=10000;
10000 rows inserted
SQL> commit;
Commit complete
SQL> exec dbms_stats.gather_table_stats(user,'t_index',cascade=>true);
PL/SQL procedure successfully completed
--增加表記錄索引的clustering_factor會增加
SQL> select index_name,clustering_factor from user_indexes where index_name='IDX_T_INDEX';
INDEX_NAME CLUSTERING_FACTOR
------------------------------ -----------------
IDX_T_INDEX 121
理想情況下index的clustering_factor與表的塊數相同,這樣掃描的資料塊很少即透過rowid只掃描很少的資料塊就可以定位到表的記錄
最差情況下是index的clustering_factor與表的記錄數相同,這樣要掃描資料塊很多,才可以定位到表的記錄
也就是說索引塊儲存的rowid與表儲存的記錄並不能從順序進一一對應,這樣就會產生透過rowid掃描表的資料塊很多所以掃描的成本很高,導致大量的物理io出現
也就可能會出現db file sequential read很高的情況
處理這種情況,有如下幾個方法;
1,採用全表掃描替換索引掃描,即不用索引了,直接用全表索引,可以用hint full實現
2,如果表上有其它的索引,可以考慮下采用其它的索引替換這個CF高的索引
3,根據表的索引列建立新個表,這樣cf自然就減少了,即:create 新表 as select * from 老表 order by 索引列;
注意:cf高並不定就會導致產生效能問題,這隻能出現效能問題一個因素,要綜合分析
---如果索引的儲存順序與表的儲存順序不同,則索引的cf很高,導致產生大量的物理io,從而db file sequential read很高
SQL> create table t_index as select object_id,object_name from dba_objects order by object_name;--以object_name順序儲存表記錄
Table created
SQL> create index idx_t_index on t_index(object_id);--而索引則以object_id順序方式儲存,導致cf極高與表的記錄數相同,導致rowid很多次重複掃描同一個資料塊才到得到表記錄
Index created
SQL> exec dbms_stats.gather_table_stats(user,'t_index',cascade=>true);
PL/SQL procedure successfully completed
SQL> select index_name,clustering_factor from user_indexes where index_name='IDX_T_INDEX';
INDEX_NAME CLUSTERING_FACTOR
------------------------------ -----------------
IDX_T_INDEX 34544
SQL> select blocks from user_tables where table_name='T_INDEX';
BLOCKS
----------
341
--重新整理緩衝池
SQL> alter system flush buffer_cache;
System altered
---要加where 條件,不然會走快速索引全掃描,而它不會產生等待事件db file sequential read
SQL> select count(object_id) from t_index where object_id between 2300 and 4800;
COUNT(OBJECT_ID)
----------------
2501
--上述使用者會話的db file sequential read等待
SQL> select event,total_waits,time_waited,average_wait from v$session_event where sid=41 order by total_waits desc;
EVENT TOTAL_WAITS TIME_WAITED AVERAGE_WAIT
---------------------------------------------------------------- ----------- ----------- ------------
SQL*Net message to client 35 0 0
SQL*Net message from client 34 3265 96.02
db file sequential read 20 18 0.92 ----
Disk file operations I/O 3 0 0.07
events in waitclass Other 1 2 1.67
log file sync 1 0 0.04
db file scattered read 1 6 6.13
7 rows selected
---如果以有序方式儲存表記錄,此時索引的cf很低與表資料塊一樣
SQL> create table t_index as select object_id,object_name from dba_objects order by object_id;--以object_name順序儲存表記錄
Table created
SQL> create index idx_t_index on t_index(object_id);--而索引則以object_id順序方式儲存,導致cf極高與表的記錄數相同,導致rowid很多次重複掃描同一個資料塊才到得到表記錄
Index created
SQL> exec dbms_stats.gather_table_stats(user,'t_index',cascade=>true);
PL/SQL procedure successfully completed
SQL> select index_name,clustering_factor from user_indexes where index_name='IDX_T_INDEX';
INDEX_NAME CLUSTERING_FACTOR
------------------------------ -----------------
IDX_T_INDEX 333
SQL> select blocks from user_tables where table_name='T_INDEX';
BLOCKS
----------
341
EVENT TOTAL_WAITS TIME_WAITED AVERAGE_WAIT
---------------------------------------------------------------- ----------- ----------- ------------
SQL*Net message to client 41 0 0
SQL*Net message from client 40 2983 74.56
db file sequential read 3 0 0.08 ---當index cf很低時,db file sequential read很高了
Disk file operations I/O 3 0 0.06
events in waitclass Other 1 7 7.49
log file sync 1 0 0.41
db file scattered read 1 3 2.53
7 rows selected
小結:
如果db file sequential read很高,先從sql查起,先看下sql對應的統計資訊是否準確,索引的clustering factor是否過高,
考慮是否要重建下索引
clustering factor如果過高,oracle cbo會優先選取full table scan而非索引掃描,因為索引掃描的成本更高
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9240380/viewspace-761688/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- db file sequential read等待事件事件
- 【等待事件】db file sequential read事件
- 等待事件db file sequential read、db file scattered read和direct read的區別事件
- 【TUNE_ORACLE】等待事件之IO等待“db file sequential read”Oracle事件
- db file scattered read等待事件事件
- 【等待事件】db file scattered read事件
- 0316理解db file parallel read等待事件Parallel事件
- 0322理解db file parallel read等待事件2Parallel事件
- I/O上的等待事件 —— control file sequential read/control file parallel write事件Parallel
- 【TUNE_ORACLE】等待事件之IO等待“db file scattered read”Oracle事件
- [20210315]理解db file parallel read等待事件3.txtParallel事件
- [20210315]理解db file parallel read等待事件4.txtParallel事件
- 【WAIT】 log file sync等待事件說明AI事件
- [20181130]control file sequential read.txt
- 【TUNE_ORACLE】等待事件之IO等待“db file parallel write”Oracle事件Parallel
- Oracle:db file scattered readOracle
- [20181129]大量的control file sequential read.txt
- direct path read/read temp等待事件事件
- read by other session等待事件Session事件
- read by other session 等待事件分析Session事件
- log file sync等待事件事件
- 【等待事件】log file sync事件
- cell single block physical read等待事件BloC事件
- buffer busy wait 等待事件說明(轉)AI事件
- 【TUNE_ORACLE】等待事件之IO等待“read by other session”Oracle事件Session
- 【TUNE_ORACLE】等待事件之IO等待“direct path read”Oracle事件
- oracle等待事件之cursor:pin S wait on XOracle事件AI
- 【TUNE_ORACLE】等待事件之日誌等待“log file sync”Oracle事件
- 常見的wait等待事件及處理(zt)AI事件
- log file sync等待事件處理思路事件
- 【TUNE_ORACLE】等待事件之日誌等待“log file parallel write”Oracle事件Parallel
- [20200120]oracle wait event "enq: SQ – contention" and DBA_DB_LINK_SOURCES.txtOracleAIENQ
- [20201204]關於等待事件Log File Sync.txt事件
- MXNet: wait_to_read 方法AI
- 等待事件wait for a undo record 與 fast_start_parallel_rollback引數事件AIASTParallel
- Oracle10g等待事件型別wait_class說明Oracle事件型別AI
- Tkinter 吐槽之二:Event 事件在子元素中共享事件
- Oracle 19c中的等待事件分類 Event WaitsOracle事件AI
- MySQL使用event等待事件進行資料庫效能診斷MySql事件資料庫