Oracle Lob型別相關引數以及效能影響
Oracle Lob型別是Oracle資料庫提供的一種將非標準格式檔案或者資訊儲存在資料庫儲存系統的一種列型別。相對於傳統的關係型資料,Lob型別的資料覆蓋型別更加多樣,同樣也就面對更多的儲存、檢索和更新方面的效能問題。
目前,Oracle顯示支援的Lob型別子類包括四個,分別為CLOB、BLOB、NLOB和BFILE。針對不同的資料型別,我們選擇不同的Lob子型別進行匹配。在四種型別中,前三種是真實將資料儲存在資料庫中,而BFILE的真實資料則是儲存在資料庫外。
本篇將針對Lob型別在儲存上使用的一些特殊屬性,進行簡單的介紹說明。同時推薦一些常用的Lob儲存最佳化手段。
1、LobSegment和LogIndex
包括Lob型別列的資料表在段結構上存在一些特殊性。最直接的表現就是Lob資料段和Lob索引段的額外建立。
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 – Production
當我們建立一個資料表T,其中包括lob型別列時。
SQL> create table t (id number, cl clob);
Table created
SQL> select segment_name, segment_type, tablespace_name from user_segments;
SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME
------------------------------ ------------------ ------------------------------
SYS_LOB0000056106C00002$$ LOBSEGMENT USERS
T TABLE USERS
SYS_IL0000056106C00002$$ LOBINDEX USERS
9 rows selected
當資料表中有一個lob型別列時,Oracle會自動多建立出兩個列,一個是儲存lob資料的lob segment,另一個是對這個lob列生成的索引。注意,這個索引是由Oracle自動建立和管理,與lob列共生不能被單獨刪除。
此處存在一些經驗實踐專案,如果lob列對應的段和索引很大時,處於平衡IO的目的,可以考慮將lob列段和索引與資料表分開,單獨放置在其他表空間上。進而實現放置在不同資料磁碟的目的。這部分實驗可以參見筆者之前文章《Oracle Lob型別儲存淺析》(http://space.itpub.net/17203031/viewspace-708336)。
注意,這裡我們的Lob資料段和索引段是要放置在同一個表空間中的。這個與我們通常的經驗相左。在Oracle 8i中,使用者是可以指定lob index的建立和管理的。但是從9i開始,這種控制權就被Oracle內部所回收,如果我們試圖使用8i時代的DDL語句進行指定,將lob資料和索引分離儲存,從前端上執行語句是不會有錯誤報出的。但是最終結果上沒有任何變化。相當於強制要求lob data segment和lob index segment存放在同一個表空間上。
2、Lob資料表儲存引數
Lob列資料和一般資料存在很大的差異,所以在儲存方面也有很多獨特的特性存在。下面分別介紹一些與Lob儲存相關的重要引數型別和含義。
CREATE TABLE "SCOTT"."T"
( "ID" NUMBER,
"CL" CLOB
)
TABLESPACE "USERS"
LOB ("CL") STORE AS (
TABLESPACE "USERS" ENABLE STORAGE IN ROW CHUNK 8192 PCTVERSION 10
NOCACHE LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)) ;
上面是將資料表T的建立DDL語句抽取出的程式碼片段。其中標註紅色的部分,明顯是針對Lob型別列CL進行的獨特store引數特性。其中包括enable storeage in row、chunk、pctversion/retention、cache和logging。這些引數的設定與Oracle Lob類物件儲存和效能息息相關。
ü Chunk——lob物件儲存最小單元
通常情況下,普通資料儲存是以位元組byte為單位寫入到資料塊datablock中。而lob型別存在一些特殊。LobSegment作為Lob資料的主體,是以chunk作為最小的分配單元。一個chunk的大小是資料塊大小db_block_size的整數倍。最大為32K。
一個chunk只能儲存一個lob物件的資料。如果出現填不滿的情況,空閒空間是被置空的。
SQL> select table_name, column_name, chunk from user_lobs;
TABLE_NAME COLUMN_NAM CHUNK
---------- ---------- ----------
T CL 8192
如果一個chunk是8K的空間,對一個lob只有1K的大小,那麼Oracle為這個lob只會分配一個chunk,而且這個chunk是為了這個lob唯一獨佔的。剩餘的7K空間是剩下留空的。
同資料塊大小db_block_size確定之後不能修改有差別,chunk是資料lob段級別的引數。從上面的定義語句可以看出,即使在一個資料表中有多個lob列,也是可以分別制定不同的chunk大小的。所以說,chunk大小的選擇要針對lob的實際而“度身定製”!
一旦確定了chunk的大小,就不能在資料表中進行修改了。
那麼為lob選擇chunk大小是依據什麼準則呢?根據Oracle推薦,如果lob列儲存的資料是小於32K,那麼設定的chunk大小建議為lob的60%比較合適。如果lob列儲存的資料是大於32K,那麼建議設定chunk的大小為經常進行update lob變化的大小。
ü In-row storage and out-of-row storage
Oracle的確為了lob列值過大的情況,準備了專門lobsegment空間。但是實際上,Oracle是可以選擇lob資料的儲存方式的。Enable storage in row就意味著是否可以in row儲存功能,提供將lob資料儲存在資料段,和其他列儲存在一起的可能。
當我們開啟了in row storage,Oracle就會根據處理lob的大小選擇是否將其儲存在資料行中,而不是專門的lobsegment。當lob大小小於4000 bytes,Oracle會將它儲存在資料表段中,和同行的其他列儲存在一起。否則,才會儲存在專門的lobsegment中。如果lob資料是儲存在lobsegment裡,那麼資料行對應的位置上只會有一個很小的指向資訊,記錄對應的lobsegment位置。
SQL> select table_name, column_name, in_row from user_lobs;
TABLE_NAME COLUMN_NAM IN_ROW
---------- ---------- ------
T CL YES
對lob store in row的情況而言,資料行的行遷移(row migration)和行連結(row chaining)是一直存在的。而且隨著資料塊大小與lob分配不匹配,這兩種現象會越來越嚴重。對lob store in row的資料來說,是不儲存在chunk單元上的。
如果lob資料儲存在其他的資料段上,那麼意味著我們每次讀取一行全部內容,都需要讀多個資料段的內容。這個顯然不是我們期望的結果。所以,在一般情況下,我們都會選擇enable storage in row來最佳化儲存。
考慮使用disable storage in row的可能性不是沒有,如果我們通常瀏覽資料是不包括lob型別或者很少包括lob型別,可以優先選擇使用lob型別。
ü Cache/NoCache
普通資料表也是有cache引數選項,那麼引數意味著資料塊讀入到buffer cache中的管理策略:是一直駐留(Keep Pool)、常規駐留(Default Pool)還是用後清除(Recycle Pool)。
對Lob資料而言,cache和nocache的含義不同,意味著在使用訪問lob型別資料的時候,是否透過buffer cache進行讀寫。如果是nocache選項,則意味著Oracle在操作該Lob列的時候會繞開Buffer Cache,進行direct write/read操作。
SQL> select table_name, column_name, cache from user_lobs;
TABLE_NAME COLUMN_NAM CACHE
---------- ---------- ----------
T CL NO
設定這個引數的背景是lob型別資料在buffer cache中的管理問題。有時候由於體積等原因,buffer cache中的lob型別資料是會帶來很多的效能問題,特別是將其flush出buffer cache的過程。
通常情況下,我們還是希望設定為cache的,用來最佳化效能。直接對檔案的direct write/read通常不會有很好的效能。
注意:cache/nocache引數是針對在lobsegment中以chunk儲存的資料而言的,對能夠in-row storage的lob而言,這個是不起作用的。因為in-row是以data block為基本操作單位。
ü Lob型別資料的一致讀consisten read
多版本一致讀、當前讀是Oracle資料庫具有的獨特屬性,也是其最重要的特性之一。藉助undo表空間的前映象資料儲存,Oracle Server Process可以訪問到一些特定時間點(SCN)的資料,作為一致性讀取、免於髒資料。
但對於Lob型別而言,一致讀問題同樣存在。Oracle需要一種保留Lob資料映象的機制,儲存一系列old version。目前,Oracle提供了兩種維持機制來進行控制:基於時間的版本保留retention和基於空間的版本保留pctversion。
SQL> select table_name, column_name, pctversion, retention from user_lobs;
TABLE_NAME COLUMN_NAM PCTVERSION RETENTION
---------- ---------- ---------- ----------
T CL 900
Retention是表示採用基於時間版本保留策略。簡單的說,就是儘量保證保留一個時間段內的資料lob版本不會清除掉。在資料庫版本的相容性版本設定在9.2.0.0以上,並且undo_management引數值為true時,lob是預設直接使用retetion設定的。同時,使用的引數值與系統引數undo_retention相同。
SQL> show parameter comp
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
compatible string 10.2.0.1.0
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
引數pctversion只對於logsegment中使用chunk儲存的資料其效果。當pctversion=0的時候,表示舊版本資料是可以被其他事務產生的版本佔用。如果設定為100,就表示;舊版本資料永遠都不會被覆寫使用。
SQL> alter table t move lob(cl) store as t_segment (pctversion 10 disable storage in row);
Table altered
SQL> select table_name, column_name, pctversion, retention, in_row from user_lobs;
TABLE_NAME COLUMN_NAM PCTVERSION RETENTION IN_ROW
---------- ---------- ---------- ---------- ------
T CL 10 NO
ü Logging/NoLogging
設定logging屬性表示進行Lob資料變化的時候,要將變化的資訊記錄在redo log裡。而相反nologging表示資料不會記錄在redo log裡面。
注意幾個問題:當Lob資料設定為cache的時候,自動就是logging屬性。如果設定為nologging,只是lobsegment部分的資料變化不會寫redo log,不會影響到其他的in row和column列的資料redo記錄工作。
3、結論
Lob型別是Oracle的一種較為特殊的資料型別。和其他資料相比具有儲存、使用上的特殊性。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-708418/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL效能相關引數MySql
- Python 序列型別以及函式引數型別Python型別函式
- Java教程:影響MySQL效能的配置引數JavaMySql
- Oracle安裝相關Linux引數(轉)OracleLinux
- Oracle direct path read相關隱含引數Oracle
- 【OPTIMIZATION】Oracle影響優化器選擇的相關技術Oracle優化
- Oracle undo保留時間的幾個相關引數Oracle
- pga相關引數
- Mysql BLOB、BLOB與TEXT區別及效能影響、將BLOB型別轉換成VARCHAR型別MySql型別
- 【PARANETERS】Oracle異常恢復相關的隱含引數Oracle
- 【LOB】Oracle Lob管理常用sqlOracleSQL
- PostgreSQL AutoVacuum 相關引數SQL
- 解析型別引數型別
- c++任意變數型別獲取相關C++變數型別
- 桌上型電腦電源相關引數說明
- 【LOB】Oracle lob管理常用語句Oracle
- JVM實用引數(一)JVM型別以及編譯器模式JVM型別編譯模式
- Spark的相關引數配置Spark
- MySQL 連線相關引數MySql
- 【Scala之旅】型別引數型別
- 數字化轉型的影響是什麼?數字化轉型對企業的影響?
- Hellow C# unity學習記錄(7)值型別引用型別以及引數傳遞C#Unity型別
- 磁碟排序對Oracle資料庫效能的影響PT排序Oracle資料庫
- 影響Oracle標量子查詢效能的三個因素Oracle
- 資料庫管理-第123期 Oracle相關兩個引數(202301205)資料庫Oracle
- JVM 引數調整對 sortx 的影響JVM
- oracle鎖級別相關測試Oracle
- ORACLE並行相關的引數Oracle並行
- Android小知識-剖析Retrofit中ServiceMethod相關引數以及建立過程Android
- [20190531]lob型別pctversion 和 retention.txt型別
- std::packaged_task<返回型別(引數型別)>Package型別
- Oracle11g 自動化建庫及調整相關引數Oracle
- Java™ 教程(有界型別引數)Java型別
- C++型別引數化C++型別
- mybatis引數型別錯誤MyBatis型別
- 4.2.10.1 Oracle Restart 相關變數配置OracleREST變數
- oracle數值型別漫談Oracle型別
- 函式引數 引數定義函式型別函式型別
- 【效能】Oracle表並行對邏輯遷移後查詢效能的影響Oracle並行