Ⅰ oracle 並行模式(parallel)
一般表數據量比較大(超過100萬)時,可以使用parallel強制啟動並行度來提升查詢速度
用法:/*+parallel(table_short_name,cash_number)*/
可以加到insert、delete、update、select的後面來使用
比如:select /*+paralle(t,32)*/ from table t; table_short_name使用別名,Parallel後面的數字,越大,執行效率越高,一般用8,10,12,16,32。不過,數值越大,佔用的資源也會相對增大。如果在查詢where後的條件有加索引查詢效率會大大提高。
Ⅱ oracle並行parallel查詢不準確
Oracle 並行查詢(parallel query)不準確的可能原因有:1、Oracle進程的參數配置問題;2、sql的結構不正確;3、並行查詢處理的資源不足;4、Oracle索引的結構不正確;5、垃圾數據的存在
Ⅲ OracleRedo並行機制
Redo log 是用於恢復和一個高級特性的重要數據 一個redo條目包含了相應操作導致的資料庫變化的所有信息 所有redo條目最終都要被寫入redo文件中去 Redo log buffer是為了避免Redo文件IO導致性能瓶頸而在sga中分配出的一塊內存 一個redo條目首先在用戶內存(PGA)中產生 然後由oracle服務進程拷貝到log buffer中 當滿足一定條件時 再由LGWR進程寫入redo文件 由於log buffer是一塊 共享 內存 為了避免沖突 它是受到redo allocation latch保護的 每個服務進程需要先獲取到該latch才能分配redo buffer 因此在高並發且數據修改頻繁的oltp系統中 我們通常可以觀察到redo allocation latch的等待 Redo寫入redo buffer的整個過程如下在PGA中生產Redo Enrey > 服務進程獲取Redo Copy latch(存在多個 CPU_COUNT* ) > 服務進程獲取redo allocation latch(僅 個) > 分配log buffer > 釋放redo allocation latch > 將Redo Entry寫入Log Buffer > 釋放Redo Copy latch;
shared strand
為了減少redo allocation latch等待 在oracle 中 引入了log buffer的並行機制 其基本原理就是 將log buffer劃分為多個小的buffer 這些小的buffer被成為strand(為了和之後出現的private strand區別 它們被稱之為shared strand) 每一個strand受到一個單獨redo allocation latch的保護 多個shared strand的出現 使原來序列化的redo buffer分配變成了並行的過程 從而減少了redo allocation latch等待
shared strand的初始數據量是由參數log_paralleli *** 控制的;在 g中 該參數成為隱含參數 並新增參數_log_paralleli *** _max控制shared strand的最大數量;_log_paralleli *** _dynamic則控制是否允許shared strand數量在_log_paralleli *** 和_log_paralleli *** _max之間動態變化
HELLODBA >selectnam ksppinm val KSPPSTVL nam ksppdesc fromsys x$ksppi nam sys x$ksppsv val where nam indx = val indx AND nam ksppinm LIKE _% AND upper(nam ksppinm) LIKE %LOG_PARALLE% ; KSPPINMKSPPSTVL KSPPDESC _log_paralleli *** Number of log buffer strands_log_paralleli *** _max Maximum number of log buffer strands_log_paralleli *** _dynamic TRUE Enable dynamic strands每一個shared strand的大小 = log_buffer/(shared strand數量) strand信息可以由表x$kcrfstrand查到(包含shared strand和後面介紹的private strand g以後存在)
HELLODBA >select indx strand_size_kcrfa from x$kcrfstrand where last_buf_kcrfa != ; INDX STRAND_SIZE_KCRFA HELLODBA >show parameter log_buffer NAME TYPEVALUE log_buffer integer
關於shared strand的數量設置 個cpu之內最大默認為 當系統中存在redo allocation latch等待時 每增加 個cpu可以考慮增加 個strand 最大不應該超過 並且_log_paralleli *** _max不允許大於cpu_count
注意 在 g中 參數_log_paralleli *** 被取消 shared strand數量由_log_paralleli *** _max _log_paralleli *** _dynamic和cpu_count控制
Private strand
為了進一步降低redo buffer沖突 在 g中引入了新的strand機制——Private strand Private strand不是從log buffer中劃分的 而是在shared pool中分配的一塊內存空間
HELLODBA >select * from V$sgastat where name like %strand% ;POOL NAME BYTES shared pool private strands HELLODBA >select indx strand_size_kcrfa from x$kcrfstrand where last_buf_kcrfa = ;INDX STRAND_SIZE_KCRFAPrivate strand的引入為Oracle的Redo/Undo機制帶來很大的變化 每一個Private strand受到一個單獨的redo allocation latch保護 每個Private strand作為 私有的 strand只會服務於一個活動事務 獲取到了Private strand的用戶事務不是在PGA中而是在Private strand生成Redo 當flush private strand或者mit時 Private strand被批量寫入log文件中 如果新事務申請不到Private strand的redo allocation latch 則會繼續遵循舊的redo buffer機制 申請寫入shared strand中 事務是否使用Private strand 可以由x$ktcxb的欄位ktcxbflg的新增的第 位鑒定
HELLODBA >select decode(bitand(ktcxbflg ) ) used_private_strand count(*) from x$ktcxb where bitand(ksspaflg ) != and bitand(ktcxbflg ) != group by bitand(ktcxbflg );USED_PRIVATE_STRAND COUNT(*)對於使用Private strand的事務 無需先申請Redo Copy Latch 也無需申請Shared Strand的redo allocation latch 而是flush或mit是批量寫入磁碟 因此減少了Redo Copy Latch和redo allocation latch申請/釋放次數 也減少了這些latch的等待 從而降低了CPU的負荷 過程如下
事務開始 > 申請Private strand的redo allocation latch (申請失敗則申請Shared Strand的redo allocation latch) > 在Private strand中生產Redo Enrey > Flush/Commit > 申請Redo Copy Latch > 服務進程將Redo Entry批量寫入Log File > 釋放Redo Copy Latch > 釋放Private strand的redo allocation latch
注意 對於未能獲取到Private strand的redo allocation latch的事務 在事務結束前 即使已經有其它事務釋放了Private strand 也不會再申請Private strand了
每個Private strand的大小為 K g中 shared pool中的Private strands的大小就是活躍會話數乘以 K 而 g中 在shared pool中需要為每個Private strand額外分配 k的管理空間 即 數量* k
g:SQL> select * from V$sgastat where name like %strand% ;POOL NAME BYTES shared pool private strands HELLODBA >select trunc(value * KSPPSTVL / ) * * from (select value from v$parameter where name = transactions ) a (select val KSPPSTVL from sys x$ksppi nam sys x$ksppsv val where nam indx = val indx AND nam ksppinm = _log_private_paralleli *** _mul ) b;TRUNC(VALUE*KSPPSTVL/ )* * g:HELLODBA >select * from V$sgastat where name like %strand% ;POOL NAME BYTES shared pool private strands HELLODBA >select trunc(value * KSPPSTVL / ) * ( + ) * from (select value from v$parameter where name = transactions ) a (select val KSPPSTVL from sys x$ksppi nam sys x$ksppsv val where nam indx = val indx AND nam ksppinm = _log_private_paralleli *** _mul ) b;TRUNC(VALUE*KSPPSTVL/ )*( + )*Private strand的數量受到 個方面的影響 logfile的大小和活躍事務數量
參數_log_private_mul指定了使用多少logfile空間預分配給Private strand 默認為 我們可以根據當前logfile的大小(要除去預分配給log buffer的空間)計算出這一約束條件下能夠預分配多少個Private strand
HELLODBA >select bytes from v$log where status = CURRENT ;BYTES HELLODBA >select trunc(((select bytes from v$log where status = CURRENT ) (select to_number(value) from v$parameter where name = log_buffer ))* (select to_number(val KSPPSTVL) from sys x$ksppi nam sys x$ksppsv val where nam indx = val indx AND nam ksppinm = _log_private_mul ) / / ) as calculated private strands from al;calculated private strands HELLODBA >select count( ) actual private strands from x$kcrfstrand where last_buf_kcrfa = ;actual private strands當logfile切換後(和checkpoint一樣 切換之前必須要將所有Private strand的內容flush到logfile中 因此我們在alert log中可能會發現日誌切換信息之前會有這樣的信息 Private strand flush not plete 這是可以被忽略的) 會重新根據切換後的logfile的大小計算對Private strand的限制
HELLODBA >alter system switch logfile;System altered HELLODBA >select bytes from v$log where status = CURRENT ;BYTES HELLODBA >select trunc(((select bytes from v$log where status = CURRENT ) (select to_number(value) from v$parameter where name = log_buffer ))* (select to_number(val KSPPSTVL) from sys x$ksppi nam sys x$ksppsv val where nam indx = val indx AND nam ksppinm = _log_private_mul ) / / ) as calculated private strands from al;calculated private strands HELLODBA >select count( ) actual private strands from x$kcrfstrand where last_buf_kcrfa = ;actual private strands參數_log_private_paralleli *** _mul用於推算活躍事務數量在最大事務數量中的百分比 默認為 Private strand的數量不能大於活躍事務的數量
HELLODBA >show parameter transactionsNAME TYPE VALUE transactions integer transactions_per_rollback_segment integer HELLODBA >select trunc((select to_number(value) from v$parameter where name = transactions ) * (select to_number(val KSPPSTVL) from sys x$ksppi nam sys x$ksppsv val where nam indx = val indx AND nam ksppinm = _log_private_paralleli *** _mul ) / ) as calculated private strands from al;calculated private strands HELLODBA >select count( ) actual private strands from x$kcrfstrand where last_buf_kcrfa = ;actual private strands注 在預分配Private strand時 會選擇上述 個條件限制下最小一個數量 但相應的shared pool的內存分配和redo allocation latch的數量是按照活躍事務數預分配的
lishixin/Article/program/Oracle/201311/17848
Ⅳ oracle並行查詢失敗,資料庫配置
解決方法如下:
保證添加的並行和查詢中的保持一致,並且保證查詢參數跟資料庫表中的數據類型一致。
Ⅳ oracle開並行資料庫時間
sql執行時間很長超過10分鍾。在OLAP系統中,當表的數據量很大,超過100W,sql執行時間很長超過10分鍾,且執行計劃正常時考慮開啟並行資料庫。OracleDatabase,又名OracleRDBMS,或簡稱Oracle,是甲骨文公司的一款關系資料庫管理系統。