oracle 11G direct path read 很美也很傷人,oracle11g
direct path read
在11g中,全表掃描可能使用direct path read方式,繞過buffer cache,這樣的全表掃描就是物理讀了。
在10g中,都是通過gc buffer來讀的,所以不存在direct path read的問題。
direct path read較高的可能原因有:
1. 大量的磁碟排序操作,order by, group by, union, distinct, rollup, 無法在PGA中完成排序,需要利用temp資料表空間進行排序。 當從暫存資料表空間中讀取排序結果時,會產生direct path read.
2. 大量的Hash Join操作,利用temp資料表空間儲存hash區。
3. SQL語句的平行處理
4. 大表的全表掃描,在中,全表掃描的演算法有新的變化,根據表的大小、快取的大小等資訊,決定是否繞過SGA直接從磁碟讀Oracle11g取資料。而10g則是全部通過快取讀取資料,稱為table scan(large)。11g認為大表全表時使用直接路徑讀,可能比10g中的資料檔案散列讀(db file scattered reads)速度更快,使用的latch也更少。
大量的direct path read等待時間最可能是一個應用程式問題。 direct path read事件由SQL語句驅動,這些SQL語句執行來自臨時的或常規的資料表空間的直接讀取操作。 當輸入的內容大於PGA中的工作區域時,帶有需要排序的函數的SQL語句將排序結果寫入到暫存資料表空間中,暫存資料表空間中的排序次序串隨後被合并,用於提供最終的結果。讀取排序結果時,Oracle會話在direct path read等待事件上等待。DB_FILE_DIRECT_IO_COUNT初始化參數可能影響direct path read的效能。
一個隱含參數:
_serial_direct_read = false 禁用direct path read
_serial_direct_read = true 啟用direct path read
alter sytem set "_serial_direct_read"=never scope=both sid='*'; 可以顯著減少direct path read
看起來很美 當是它帶來另外個等待事件,那就是要把緩衝中的髒資料刷回資料檔案中。激發check point 事件,DBWR寫的任務很頻繁。
大量的讀IO導致IO緩慢,緩慢的IO又讓DBWR寫得更慢,同時check point事件會阻塞 DML。 在OLTP方面是很嚴重的事故。
因為應用程式存在大量的全表查詢的語句。
serial number read/write 是什
直接路徑讀/寫
通常發生在Oracle直接讀資料到進程PGA時,這個讀取不需要經過SGA。直接路徑讀等待事件的3個參數分別是file number(指絕對檔案號)、first dba、block cnt數量。在Oracle 10g/11g中,這個等待事件被歸於User I/O一類。
db file sequential read、db file scattered read、direct path read是常見的集中資料讀方式,簡要描述了這3種方式的讀取示意。
這類讀取通常在以下情況被使用:
·磁碟排序IO操作;
·並行查詢從屬進程;
·預讀操作。
最為常見的是第一種情況。在DSS系統中,存在大量的direct path read是很正常的,但是在OLTP系統中,通常顯著的直接路徑讀(direct path read)都意味著系統應用存在問題,從而導致大量的磁碟排序讀取操作。
直接路徑寫(direct paht write)通常發生在Oracle直接從PGA寫資料到資料檔案或臨時檔案,這個寫操作可以繞過SGA。直接路徑寫等待事件的3個參數分別是:file number(指絕對檔案號)、first dba和block cnt數量,在Oracle 10g/11g中,這個等待事件同direct path read一樣被歸於User I/O一類。
這類寫入操作通常在以下情況被使用:
·直接路徑載入;
·並行DML操作;
·磁碟排序;
·對未緩衝的“LOB”段的寫入,隨後會記錄為direct path write(lob)等待。
最為常見的直接路徑寫,多數因為磁碟排序導致。對於這一寫入等待,我們應該找到I/O操作最為頻繁的資料檔案(如果有過多的排序操作,很有可能就是臨時檔案),分散負載,加快其寫入操作。
1. 磁碟排序診斷:
如果系統存在過多的磁碟排序,會導致暫存資料表空間操作頻繁,對於這種情況,可以考慮為不同使用者指派不同的暫存資料表空間,使用多個臨時檔案,寫入不同磁碟或者裸裝置,從而降低競爭,提高效能;對於Oracle 8i的資料庫,應該考慮使用本地管理(Local)的暫存資料表空間,而不是字典(dictionary)管理。
對於這種情況,在Oracle 9i之前,可以適當增加sort_area_size的大小;從Oracle 9i開始,可以適當增大pga_aggregate_target,以縮減磁碟排序對於磁碟的寫入,從而提高系統及應用響應。但是通常應該及時檢查應用,確認是否因為應用問題導致了過度排序,從而根本上解決問題。
2. 並行查詢導致效能問題:
有時候在應用系統中,不正確的使用並行查詢也會導致應用問題。Statspack的Top 5時間事件輸出顯示direct path read消耗了較高的等待時,而記憶體排序率很高甚至是100%(In-memory Sort %:100.00)顯然這裡的Direct Path Read並不是由於排序引發的,注意到另外一個等待事件(KJC: Wait for msg sends to complete)和並行有關,所以初步判斷這裡的direct path read可能和並行有關。
註:在Statspack的報告中,存在一個效能指標,稱為記憶體排序率(In-memory Sort Ratio),用于衡量系統的排序操作,這個指標就是由兩個統計資訊sorts (disk)和sorts (memory)得出:
In-memory Sort Ratio = sorts (......餘下全文>>
ORACLE EXISTS執行順序問題
首先,
這兩個查詢語句,查詢到的結果是不一樣的。
第一個語句:
SELECT COUNT(1) FROM DUAL WHERE EXISTS (SELECT 1 FROM XXX WHERE YY IS NOT NULL);結果只能是1或者0。
第二個語句:
SELECT COUNT(1) FROM XXX WHERE YY IS NOT NULL;結果就是xxx表中yy欄位不為空白的個數。
其次,
如果你只是判斷xxx表中yy欄位是否有不為空白的記錄,那麼第一個語句效率應該說高一些。
我的理解是這樣的,表的block(沒有索引的話)肯定是要拿到buffer cache裡面(非direct path read),只是當判斷的時候會減少一些操作,當執行判斷到第一條yy is not null的時候,就不會繼續下面的判斷操作了。
就算是這樣,我覺得效率應該也不會提升多少,頂多也就是節省了cpu的使用。
如果想具體的瞭解他們兩個語句的執行方式,可以開啟session的10046事件跟蹤一下,比較兩個sql語句執行的異同。