LOB型別
1、clob/blob
建立一個lob列時,儲存在行中的只是一個指標,當我們請求得到lob資料時,lob指標將透過lobindex找到資料的儲存位置,然後訪問lobsegment獲取資料。
表空間
lob欄位與表放在不同的表空間,主要與管理和效能有關。一方面,為lob資料單獨使用一個表空間有利於備份和恢復以及空間管理。另一方面,預設情況下lob不在快取區中進行快取,對於每個lob訪問,不論是讀還是寫,都會帶來一個IO,所以將這些物件分離到他們自己的磁碟上就很有意義。另外需要說明,logindex和logsegment總會在同一個表空間中。
in row 子句
這控制了lob資料是否總與表分開儲存。如果設定了enable storage in row(預設設定) ,小lob(最多4000位元組)就會像varchar2一樣儲存在表本身中,只有當lob超過了4000位元組時,才會移出到lobsegment中。如果lob欄位資料小於4000位元組,建議採用行記憶體儲,即預設設定。
JEL@JEL >create table t
2 (id int primary key,
3 in_row clob,
4 out_row clob)
5 lob (in_row) store as (enable storage in row)
6 lob (out_row) store as (disable storage in row);
Table created.
JEL@JEL >insert into t
2 select rownum,
3 owner||' '||object_name||' '||object_type||' '||status,
4 owner||' '||object_name||' '||object_type||' '||status
5 from all_objects;
9345 rows created.
JEL@JEL >alter session set SQL_TRACE=TRUE;
Session altered.
JEL@JEL >declare
2 l_cnt number;
3 l_data varchar2(4000);
4 begin
5 select count(*) into l_cnt from t;
6 for i in 1 .. l_cnt
7 loop
8 select in_row into l_data from t where id=i;
9 select out_row into l_data from t where id=i;
10 end loop;
11 end;
12 /
PL/SQL procedure successfully completed.
[oracle@jelephant ~]$ tkprof /u01/app/oracle/admin/JEL/udump/jel_ora_4540.trc /u01/app/oracle/admin/JEL/udump/jel_ora_4540.txt
跟蹤檔案如下:
********************************************************************************
SELECT IN_ROW
FROM
T WHERE ID=:B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 9345 0.03 0.16 0 0 0 0
Fetch 9345 0.08 0.19 0 28035 0 9345
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 18691 0.11 0.36 0 28035 0 9345
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 25 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
9345 TABLE ACCESS BY INDEX ROWID T (cr=28035 pr=0 pw=0 time=199495 us)
9345 INDEX UNIQUE SCAN SYS_C002903 (cr=18690 pr=0 pw=0 time=96206 us)(object id 10067)
********************************************************************************
SELECT OUT_ROW
FROM
T WHERE ID=:B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 9345 0.07 0.16 0 0 0 0
Fetch 9345 1.08 0.57 9345 56072 0 9345
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 18691 1.15 0.73 9345 56072 0 9345
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 25 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
9345 TABLE ACCESS BY INDEX ROWID T (cr=28035 pr=0 pw=0 time=208311 us)
9345 INDEX UNIQUE SCAN SYS_C002903 (cr=18690 pr=0 pw=0 time=102863 us)(object id 10067)
********************************************************************************
獲取in_row列顯然快的多,而且所佔的資源也遠遠少於獲取out_row列。這種行內行外儲存設定不僅會影響讀,還會影響修改。
chunk子句
lob儲存在塊(chunk)中,指向lob資料的索引會指向各個資料塊。塊(chunk)是邏輯上連續的一直資料庫塊(block),這也是lob的最小分配單元,但通常資料塊的最小分配單元是資料塊庫塊。chunk大小必須是block的整數倍。
注意兩點,第一,一個chunk只能由一個lob值使用,每個lob值會佔用至少一個chunk。如果一個表有100行,每行有一個包含7kb資料的lob。oracle就分配100個chunk,如果將chunk大小設定成32kb,就會分配100*32kb的空間,從而產生大量空間浪費。第二,讓每個lob值相應的chunk數減至最少,lobindex用於指向各個塊,塊越多,索引就越大。
pctversion子句
用於控制lob的讀一致性。lobsegment並不使用undo來記錄其修改,而是直接在lobsegment本身中維護資訊的版本,而lobindex會像其他段一樣上傳undo。修改一個lob時,oracle會分配一個新chunk,並且仍保留原來的chunk。如果回滾事務,對lobindex所做的修改會回滾,索引將再次指向原來的chunk。
如果不用undo段來儲存回滾lob所需的資訊,而且lob支援讀一致性,那麼怎麼避免ORA-1555:snapshot too old錯誤呢?這正是pctversion起作用的地方
如果處理lob是遇到了ORA-22924錯誤,解決方案是執行如下命令:
alter table tabname modify lob (lobname)(pctversion n)
cache子句
預設nocache
cache reads 允許快取從磁碟讀取得lob資料,但是lob資料的寫操作則直接寫至磁碟。cache則允許讀和寫都能快取lob資料,建議對小lob進行快取。
alter table tabname modify lob (lobname)(cache)
alter table tabname modify lob (lobname)(nocache)
2、bfile
它只是作業系統上一個檔案的指標,它用於為這些作業系統檔案提供只讀訪問。
JEL@JEL >create table t_file (id int primary key,os_file bfile);
Table created.
JEL@JEL >create or replace directory my_dir as '/home/oracle/';
Directory created.
JEL@JEL >insert into t_file values (1,bfilename('MY_DIR','db.txt'));
1 row created.
JEL@JEL >commit;
Commit complete.
JEL@JEL >select dbms_lob.getlength(os_file) from t_file;
DBMS_LOB.GETLENGTH(OS_FILE)
---------------------------
951
檔案大小為951kb,注意儲存是要求MY_DIR必須為大寫。
讀取檔案:
JEL@JEL >grant read,write on directory my_dir to public;
Grant succeeded.
JEL@JEL > SET SERVEROUTPUT ON
指令碼如下:
declare
fhandle utl_file.file_type;
f_buffer varchar2(4000);
begin
fhandle := utl_file.fopen('MY_DIR','db.txt','r');
loop
begin
utl_file.get_line(fhandle,f_buffer);
dbms_output.put_line(f_buffer);
exception
when no_data_found then
exit;
end;
end loop;
utl_file.fclose(fhandle);
end;
建立一個lob列時,儲存在行中的只是一個指標,當我們請求得到lob資料時,lob指標將透過lobindex找到資料的儲存位置,然後訪問lobsegment獲取資料。
表空間
lob欄位與表放在不同的表空間,主要與管理和效能有關。一方面,為lob資料單獨使用一個表空間有利於備份和恢復以及空間管理。另一方面,預設情況下lob不在快取區中進行快取,對於每個lob訪問,不論是讀還是寫,都會帶來一個IO,所以將這些物件分離到他們自己的磁碟上就很有意義。另外需要說明,logindex和logsegment總會在同一個表空間中。
in row 子句
這控制了lob資料是否總與表分開儲存。如果設定了enable storage in row(預設設定) ,小lob(最多4000位元組)就會像varchar2一樣儲存在表本身中,只有當lob超過了4000位元組時,才會移出到lobsegment中。如果lob欄位資料小於4000位元組,建議採用行記憶體儲,即預設設定。
JEL@JEL >create table t
2 (id int primary key,
3 in_row clob,
4 out_row clob)
5 lob (in_row) store as (enable storage in row)
6 lob (out_row) store as (disable storage in row);
Table created.
JEL@JEL >insert into t
2 select rownum,
3 owner||' '||object_name||' '||object_type||' '||status,
4 owner||' '||object_name||' '||object_type||' '||status
5 from all_objects;
9345 rows created.
JEL@JEL >alter session set SQL_TRACE=TRUE;
Session altered.
JEL@JEL >declare
2 l_cnt number;
3 l_data varchar2(4000);
4 begin
5 select count(*) into l_cnt from t;
6 for i in 1 .. l_cnt
7 loop
8 select in_row into l_data from t where id=i;
9 select out_row into l_data from t where id=i;
10 end loop;
11 end;
12 /
PL/SQL procedure successfully completed.
[oracle@jelephant ~]$ tkprof /u01/app/oracle/admin/JEL/udump/jel_ora_4540.trc /u01/app/oracle/admin/JEL/udump/jel_ora_4540.txt
跟蹤檔案如下:
********************************************************************************
SELECT IN_ROW
FROM
T WHERE ID=:B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 9345 0.03 0.16 0 0 0 0
Fetch 9345 0.08 0.19 0 28035 0 9345
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 18691 0.11 0.36 0 28035 0 9345
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 25 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
9345 TABLE ACCESS BY INDEX ROWID T (cr=28035 pr=0 pw=0 time=199495 us)
9345 INDEX UNIQUE SCAN SYS_C002903 (cr=18690 pr=0 pw=0 time=96206 us)(object id 10067)
********************************************************************************
SELECT OUT_ROW
FROM
T WHERE ID=:B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 9345 0.07 0.16 0 0 0 0
Fetch 9345 1.08 0.57 9345 56072 0 9345
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 18691 1.15 0.73 9345 56072 0 9345
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 25 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
9345 TABLE ACCESS BY INDEX ROWID T (cr=28035 pr=0 pw=0 time=208311 us)
9345 INDEX UNIQUE SCAN SYS_C002903 (cr=18690 pr=0 pw=0 time=102863 us)(object id 10067)
********************************************************************************
獲取in_row列顯然快的多,而且所佔的資源也遠遠少於獲取out_row列。這種行內行外儲存設定不僅會影響讀,還會影響修改。
chunk子句
lob儲存在塊(chunk)中,指向lob資料的索引會指向各個資料塊。塊(chunk)是邏輯上連續的一直資料庫塊(block),這也是lob的最小分配單元,但通常資料塊的最小分配單元是資料塊庫塊。chunk大小必須是block的整數倍。
注意兩點,第一,一個chunk只能由一個lob值使用,每個lob值會佔用至少一個chunk。如果一個表有100行,每行有一個包含7kb資料的lob。oracle就分配100個chunk,如果將chunk大小設定成32kb,就會分配100*32kb的空間,從而產生大量空間浪費。第二,讓每個lob值相應的chunk數減至最少,lobindex用於指向各個塊,塊越多,索引就越大。
pctversion子句
用於控制lob的讀一致性。lobsegment並不使用undo來記錄其修改,而是直接在lobsegment本身中維護資訊的版本,而lobindex會像其他段一樣上傳undo。修改一個lob時,oracle會分配一個新chunk,並且仍保留原來的chunk。如果回滾事務,對lobindex所做的修改會回滾,索引將再次指向原來的chunk。
如果不用undo段來儲存回滾lob所需的資訊,而且lob支援讀一致性,那麼怎麼避免ORA-1555:snapshot too old錯誤呢?這正是pctversion起作用的地方
如果處理lob是遇到了ORA-22924錯誤,解決方案是執行如下命令:
alter table tabname modify lob (lobname)(pctversion n)
cache子句
預設nocache
cache reads 允許快取從磁碟讀取得lob資料,但是lob資料的寫操作則直接寫至磁碟。cache則允許讀和寫都能快取lob資料,建議對小lob進行快取。
alter table tabname modify lob (lobname)(cache)
alter table tabname modify lob (lobname)(nocache)
2、bfile
它只是作業系統上一個檔案的指標,它用於為這些作業系統檔案提供只讀訪問。
JEL@JEL >create table t_file (id int primary key,os_file bfile);
Table created.
JEL@JEL >create or replace directory my_dir as '/home/oracle/';
Directory created.
JEL@JEL >insert into t_file values (1,bfilename('MY_DIR','db.txt'));
1 row created.
JEL@JEL >commit;
Commit complete.
JEL@JEL >select dbms_lob.getlength(os_file) from t_file;
DBMS_LOB.GETLENGTH(OS_FILE)
---------------------------
951
檔案大小為951kb,注意儲存是要求MY_DIR必須為大寫。
讀取檔案:
JEL@JEL >grant read,write on directory my_dir to public;
Grant succeeded.
JEL@JEL > SET SERVEROUTPUT ON
指令碼如下:
declare
fhandle utl_file.file_type;
f_buffer varchar2(4000);
begin
fhandle := utl_file.fopen('MY_DIR','db.txt','r');
loop
begin
utl_file.get_line(fhandle,f_buffer);
dbms_output.put_line(f_buffer);
exception
when no_data_found then
exit;
end;
end loop;
utl_file.fclose(fhandle);
end;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29337971/viewspace-1063972/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- LONG型別遷移到LOB型別(三)型別
- LONG型別遷移到LOB型別(二)型別
- LONG型別遷移到LOB型別(一)型別
- 為lob型別分配extents型別
- 移動LOB型別的索引型別索引
- Oracle - LOB(大物件資料型別)Oracle物件資料型別
- Oracle Lob型別儲存淺析Oracle型別
- Oracle LOB資料型別的處理Oracle資料型別
- expdp測試包含有lob型別的物件型別物件
- 將lob型別的index移動到其它tablespace型別Index
- 轉:11g對LOB型別的新增功能型別
- lob欄位型別轉換ora-22858型別
- Oracle Lob型別相關引數以及效能影響Oracle型別
- 測試TOM=用PLSQL載入LOB型別資料SQL型別
- Oracle11g新特性——LOB型別功能增強Oracle型別
- LOB欄位EMPTY_LOB和NULL的區別Null
- [20190531]lob型別pctversion 和 retention.txt型別
- LOB列型別的LOGGING和NOLOGGING儲存選擇型別
- 【LOB】Oracle Lob管理常用sqlOracleSQL
- 【LOB】Oracle lob管理常用語句Oracle
- ORACLE 10G下LOB_DATA欄位型別佔滿臨時表空間問題Oracle 10g型別
- Long -> lob , to_lob 轉換,遷移
- Oracle LOBOracle
- TS資料型別:型別別名/聯合型別/字面量型別/型別推論等綱要資料型別
- 淺談程式語言型別的強型別,弱型別,動態型別,靜態型別型別
- javascript基本型別 引用型別 基本包裝型別JavaScript型別
- C#的型別——值型別與引用型別C#型別
- 值型別和引用型別型別
- JavaScript引用型別-Object型別JavaScript型別Object
- mysql BLOB型別 TEXT型別MySql型別
- 值型別與引用型別型別
- Oracle LOB issueOracle
- LOB(large object)Object
- LOB學習
- js基本型別和引用型別區別JS型別
- 值型別與引用型別的區別型別
- JAVA 基本型別與 引用型別區別Java型別
- JavaScript值型別和引用型別JavaScript型別