Oracle LOB 详解
一. 官方說明
Oracle 11gR2 文檔:
LOB Storage
http://download.oracle.com/docs/cd/E11882_01/appdev.112/e18294/adlob_tables.htm
Oracle 10gR2 文檔:
LOBs in Tables
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14249/adlob_tables.htm
1.1 Creating Tables That Contain LOBs
When creating tables that contain LOBs, use the guidelines described in the followingsections:
1.1.1 Initializing Persistent LOBs to NULL or Empty
You can set apersistent LOB — -that is, a LOB column in a table, or a LOB attribute in anobject type that you defined— to beNULLor empty:
(1)Settinga Persistent LOB to NULL: A LOB settoNULLhas no locator. ANULLvalue is stored in the rowin the table, not a locator. This is the same process as for all other datatypes.
(2)Settinga Persistent LOB to Empty: By contrast, an empty LOBstored in a table is a LOB of zero length that has a locator. So, ifyouSELECTfrom an empty LOB column or attribute, then you get back alocator which you can use to populate the LOB with data using supported programmaticenvironments, such as OCI orPL/SQL(DBMS_LOB).
--NULL 與 Empty的區別是NULL 沒有locator指針,而Empty 有locator 指針。
1.1.2 Setting a Persistent LOB to NULL
You may want toset a persistent LOB value toNULLupon inserting the row in caseswhere you do not have the LOB data at the time of theINSERTor ifyou want to use a SELECTstatement, such as the following, to determinewhether the LOB holds aNULLvalue:
SELECT COUNT (*) FROM print_media WHERE ad_graphic IS NOT NULL;
SELECT COUNT (*) FROM print_media WHERE ad_graphic IS NULL;
Note that you cannot call OCI or DBMS_LOB functions on aNULLLOB, so you mustthen use an SQLUPDATEstatement to reset the LOB column to anon-NULL(or empty) value.
--如果想使用OCI 或者DBMS_LOB, LOB 列需要設置為非NULL 或者empty。
The point isthat you cannot make a function call from the supported programmaticenvironments on a LOB that isNULL.These functions only work with alocator, and if the LOB column isNULL, then there is no locator in therow.
1.1.3 Settinga Persistent LOB to Empty
You can initialize a persistent LOB toEMPTYrather thatNULL. Doing so,enables you to obtain a locator for the LOB instance without populating the LOBwith data.
To set apersistent LOB toEMPTY, use the SQLfunctionEMPTY_BLOB()orEMPTY_CLOB()intheINSERTstatement:
SQL>INSERTINTO a_table VALUES (EMPTY_BLOB());
As an alternative, you can use theRETURNINGclause to obtain the LOBlocator in one operation rather than calling a subsequent SELECT statement:
DECLARE Lob_loc BLOB; BEGIN INSERT INTO a_table VALUES (EMPTY_BLOB()) RETURNING blob_col INTO Lob_loc; /*Now use the locator Lob_loc to populate the BLOB with data */ END;
1.1.4 Initializing LOBs
You can initialize the LOBs inprint_mediaby using thefollowingINSERTstatement:
SQL>INSERTINTO print_media VALUES (1001, EMPTY_CLOB(), EMPTY_CLOB(), NULL,EMPTY_BLOB(),EMPTY_BLOB(), NULL, NULL, NULL, NULL);
This sets thevalueofad_sourcetext,ad_fltextn,ad_composite,andad_phototoan empty value, and setsad_graphictoNULL.
1.1.5 Initializing Persistent LOB Columns and Attributes to a Value
You caninitialize the LOB column or LOB attributes to a value that contains more than4G bytes of data, the limit before release 10.2.
--在Oracle 11g中初始化LOB 的內容可以超過4G,而在oracle10g里最大是4G。
A LOB can be up to 8 terabytes or more insize depending on your block size.
A LOB can be up to 128 terabytes or more insize depending on your block size.
這個是初始化的最大值,LOB可存放的最大容量:
Oracle 9iR2 是4G。
Oracle 10g 最大8T。
Oracle 11g 最大是128T。
具體取決與blocksize 的大小。
1.1.6 Initializing BFILEs to NULL or a File Name
ABFILEcanbe initialized toNULLor to a filename. To do so, you can usetheBFILENAME()function.
See Also:
"BFILENAMEand Initialization".
1.1.7 Restrictionon First Extent of a LOB Segment
The first extent of any segment requiresat least 2 blocks(ifFREELISTGROUPSwas 0). That is, the initial extent size of the segment should beat least 2 blocks. LOBs segments are different because they needat least 3 blocksin the first extent. If you try tocreate a LOB segment in a permanent dictionary managed tablespace with initial= 2 blocks, then it still works because it is possible for segments in permanent dictionary-managed tablespaces to override the default storagesetting of the tablespaces.
But if uniformlocally managed tablespaces or dictionary managed tablespaces of the temporarytype, or locally managed temporary tablespaces have an extent size of 2 blocks,then LOB segments cannot be created in these tablespaces. This is because inthese tablespace types, extent sizes are fixed and the default storage settingof the tablespaces is not ignored.
1.2 Choosinga LOB Column Data Type
1.2.1 LOBs Compared to LONG and LONG RAW Types
Table11-1lists the similarities and differences between LOBs, LONGs, andLONG RAW types.
Table 11-1 LOBs Vs. LONG RAW
|
LOB Data Type |
LONG and LONG RAW Data Type |
|
You can store multiple LOBs in a single row |
You can store only oneLONGorLONGRAWin each row. |
|
LOBs can be attributes of a user-defined data type |
This is not possible with either aLONGorLONGRAW |
|
Only the LOB locator is stored in the table column;BLOBandCLOBdata can be stored in separate tablespaces andBFILEdata is stored as an external file. For inline LOBs, the database stores LOBs that are less than approximately 4000 bytes of data in the table column. |
In the case of aLONGorLONGRAWthe entire value is stored in the table column. |
|
When you access a LOB column, you can choose to fetch the locator or the data. |
When you access aLONGorLONGRAW,the entire value is returned. |
|
A LOB can be up to 128 terabytes or more in size depending on your block size. |
ALONGorLONGRAWinstance is limited to 2 gigabytes in size. |
|
There is greater flexibility in manipulating data in a random, piece-wise manner with LOBs. LOBs can be accessed at random offsets. |
Less flexibility in manipulating data in a random, piece-wise manner withLONG or LONG RAW data.LONGs must be accessed from the beginning to the desired location. |
|
You can replicate LOBs in both local and distributed environments. |
Replication in both local and distributed environments is not possible with aLONGorLONGRAW(seeOracle Database Advanced Replication) |
1.2.2 Storing Varying-Width Character Data in LOBs
Varying-width character data inCLOBandNCLOBdata types is stored in aninternal format that is compatible with UCS2 Unicode character set format. Thisensures that there is no storage loss of character data in a varying-widthformat. Also note the following if you are using LOBs to store varying-widthcharacter data:
(1)You can create tables containingCLOBandNCLOBcolumns even if youuse a varying-widthCHARorNCHARdatabase character set.
(2)You can create a table containing a data type that has aCLOBattributeregardless of whether you use a varying-widthCHARdatabase characterset.
1.2.3 Implicit Character Set Conversions with LOBs
ForCLOBandNCLOBinstancesused in OCI (Oracle Call Interface), or any of the programmatic environmentsthat access OCI functionality, character set conversions are implicitly performed when translating from one character set to another.
TheDBMS_LOB.LOADCLOBFROMFILEAPI, performs an implicit conversion from binary data to character datawhen loading to aCLOBorNCLOB. With the exception of DBMS_LOB.LOADCLOBFROMFILE,LOB APIs do not perform implicit conversions from binary data to characterdata.
For example,when you use theDBMS_LOB.LOADFROMFILEAPI to populateaCLOBorNCLOB, you are populating the LOB with binary datafrom aBFILE. In this case, you must perform character set conversions ontheBFILEdata before callingDBMS_LOB.LOADFROMFILE.
Note:
The databasecharacter set cannot be changed from a single-byte to a multibyte character setif there are populated user-definedCLOB columns in the database tables.The national character set cannot be changedbetweenAL16UTF16andUTF8if there are populateduser-definedNCLOBcolumns in the database tables.
1.3 LOB Storage Parameters
1.3.1 Inlineand Out-of-Line LOB Storage
LOB columnsstore locators that reference the location of the actual LOB value. Dependingon the column properties you specify when you create the table, and dependingthe size of the LOB, actual LOB values are stored either in the table row(inline) or outside of the table row (out-of-line).
LOB 存儲分為2種: Inline 和 Out-Of-Line Storage。 Inline Storage 是存儲在表的空間里,而out-of-line storage 是存儲在lobsegment里的。
LOB values are stored out-of-line when any of the following situations apply:
(1)If youexplicitly specifyDISABLESTORAGEINROWforthe LOB storage clause when you create the table.
(2)If the sizeof the LOB is greater thanapproximately 4000 bytes(4000 minus system control information), regardless of the LOB storageproperties for the column.
(3)If you updatea LOB that is stored out-of-line and the resulting LOB is less thanapproximately 4000 bytes, it is still stored out-of-line.
LOB values are stored inline when any of the following conditions apply:
(1)When the sizeof the LOB stored in the given row is small, approximately 4000 bytes or less,and you either explicitly specifyENABLESTORAGEINROWorthe LOB storage clause when you create the table, or when you do not specifythis parameter (which is the default).
(2)When the LOB value isNULL(regardless of the LOB storageproperties for the column).
Using the default LOB storage properties (inline storage) canallow for better database performance; it avoids theoverhead of creating and managing out-of-line storage for smaller LOB values.If LOB values stored in your database are frequently small in size, then usinginline storage is recommended.
Note:
(1)LOB locatorsare always stored in the row.
(2)A LOB locatoralways exists for any LOB instance regardless of the LOB storage properties orLOB value -NULL, empty, or otherwise.
(3)If the LOB iscreated withDISABLE STORAGE IN ROWproperties and the Basic FilesLOB holds any data, then a minimum of one CHUNKof out-of-line storagespace is used; even when the size of the LOB is less thantheCHUNKsize.
(4)If a LOBcolumn is initialized withEMPTY_CLOB()orEMPTY_BLOB(), then noLOB value exists, not evenNULL. The row holds a LOB locator only. Noadditional LOB storage is used.
(5)LOB storageproperties do not affectBFILEcolumns.BFILEdata is always stored in operating system files outside the database.
1.3.2 Defining Tablespaceand Storage Characteristics for Persistent LOBs
When defining LOBs in a table, you can explicitly indicate the tablespace and storagecharacteristics for eachpersistent LOBcolumn.
To create aBasicFiles LOB, theBASICFILEkeyword is optional but is recommendedfor clarity, as shown in the following example:
CREATE TABLE ContainsLOB_tab (n NUMBER, c CLOB) lob (c) STORE AS BASICFILE segname (TABLESPACE lobtbs1 CHUNK 4096 PCTVERSION 5 NOCACHE LOGGING STORAGE (MAXEXTENTS 5) );For SecureFiless, theSECUREFILEkeyword is necessary, as shown in thefollowing example (assumingTABLESPACE lobtbs1isASSM):
CREATE TABLE ContainsLOB_tab1 (n NUMBER, c CLOB) lob (c) STORE AS SECUREFILE sfsegname (TABLESPACE lobtbs1 RETENTION AUTO CACHE LOGGING STORAGE (MAXEXTENTS 5) );Note:There are notablespace or storage characteristics that you can specifyforexternalLOBs (BFILEs) as they are not stored in the database.
If you must modify the LOB storage parameters on an existing LOB column, then usetheALTERTABLE... MOVEstatement. You can changetheRETENTION,PCTVERSION,CACHE,NOCACHELOGGING,NOLOGGING,orSTORAGEsettings. You can also changetheTABLESPACEusing theALTER TABLE ... MOVEstatement.
1.3.3 Assigninga LOB Data Segment Name
As shown in the previous example, specifying a name for the LOB data segment makes for a muchmore intuitive working environment. When querying the LOB data dictionary viewsUSER_LOBS,ALL_LOBS,DBA_LOBS(seeOracleDatabase Reference), you see the LOB data segment that you chose instead ofsystem-generated names.
1.3.4 LOB Storage Characteristics for LOB Column or Attribute
LOB storage characteristics that can be specified for a LOB column or a LOB attributeinclude the following:
(1)TABLESPACE
(2)PCTVERSIONorRETENTION
(3)CACHE/NOCACHE/CACHE READS
(4)LOGGING/NOLOGGING
(5)CHUNK
(6)ENABLE/DISABLESTORAGEINROW
(7)STORAGE
Note that you can specify eitherPCTVERSIONorRETENTIONfor BasicFilesLOBs, but not both. For SecureFiless, only theRETENTIONparametercan be specified.
For most users, defaults for these storagecharacteristics are sufficient. If you want to fine-tune LOB storage, thenconsider the following guidelines.
1.3.4.1 TABLESPACE and LOB Index
Best performancefor LOBs can be achieved by specifying storage for LOBs in a tablespacedifferent from the one used for the table that contains the LOB. If manydifferent LOBs are accessed frequently, then it may also be useful to specify aseparate tablespace for each LOB column or attribute in order to reduce devicecontention.
The LOB index isan internal structure that is strongly associated with LOB storage. This implies that a user may not drop the LOB index and rebuild it.
--LOB index 是隨Lobsegment 自動創建的,不能只刪除和重建LOB index。
Note:
The LOB index cannot be altered. –LOB index 不能被修改。
The system determines which tablespace to use for LOB data and LOB index depending on yourspecification in the LOB storage clause:
(1)If youdonotspecify a tablespace for the LOB data, then the tablespace ofthe table is used for the LOB data and index.
(2)If youspecify a tablespace for the LOB data, then both the LOB data and index use thetablespace that was specified.
--lobsegment 和lobindex 使用相同的表空間
1.3.4.2 Tablespace for LOB Index in Non-Partitioned Table
When creating atable, if you specify a tablespace for the LOB index for a non-partitionedtable, then your specification of the tablespace is ignored and the LOB indexis co-located with the LOB data. Partitioned LOBs do not include the LOB indexsyntax.
Specifying aseparate tablespace for the LOB storage segments enables a decrease incontention on the tablespace of the table.
1.3.4.3 PCTVERSION
When a BasicFiles LOB is modified, a new version of the BasicFiles LOB page isproduced in order to support consistent read of prior versions of theBasicFiles LOB value.
PCTVERSIONis the percentage of all used BasicFiles LOB data space that can be occupied byold versions of BasicFiles LOB data pages. As soon as old versions ofBasicFiles LOB data pages start to occupy more thanthePCTVERSIONamount of used BasicFiles LOB space, Oracle Databasetries to reclaim the old versions and reuse them. In other words, PCTVERSIONisthe percent of used BasicFiles LOB data blocks that is available for versioningold BasicFiles LOB data.
Oracle 的一致性通過UNDO 來體現,而LOB 的一致性是例外,是通過自己來實現的,就是在修改之前先copy 一下對應的chunk,chunk 是LOB的基本單位。 這個PCTVERSION就是一個用來控制回滾空間大小的一個參數,該值越大,回滾的時間相對就長,但是占用的空間也就越大。
PCTVERSION has a default of 10 (%), a minimum of 0, and amaximum of 100.
To decide whatvaluePCTVERSIONshould be set to, consider the following:
(1)How oftenBasicFiles LOBs are updated?
(2)How often theupdated BasicFiles LOBs are read?
Table 11-2 Recommended PCTVERSION Settings
|
BasicFiles LOB Update Pattern |
BasicFiles LOB Read Pattern |
PCTVERSION |
|
Updates X% of LOB data |
Reads updated LOBs |
X% |
|
Updates X% of LOB data |
Reads LOBs but not the updated LOBs |
0% |
|
Updates X% of LOB data |
Reads both updated and non-updated LOBs |
2X% |
|
Never updates LOB |
Reads LOBs |
0% |
If yourapplication requires several BasicFiles LOB updates concurrent with heavy readsof BasicFiles LOB columns, then consider using a higher valueforPCTVERSION, such as 20%.
SettingPCTVERSIONtotwice the default value allows more free pages to be used for old versions ofdata pages. Because large queries may require consistent reads of BasicFilesLOB columns, it may be useful to retain old versions of BasicFiles LOB pages.In this case, BasicFiles LOB storage may grow because the database does notreuse free pages aggressively.
If persistentBasicFiles LOB instances in your application are created and written just onceand are primarily read-only afterward, then updates are infrequent. In thiscase, consider using a lower value forPCTVERSION, such as 5% or lower.
The moreinfrequent and smaller the BasicFiles LOB updates are, the less space must bereserved for old copies of BasicFiles LOB data. If existing BasicFiles LOBs areknown to be read-only, then you could safely setPCTVERSIONto 0%because there would never be any pages needed for old versions of data.
當pctversion=0的時候,表示舊版本數據是可以被其他事務產生的版本占用。如果設置為100,就表示舊版本數據永遠都不會被覆寫使用。
SQL> alter table t move lob(cl) store ast_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_NAMPCTVERSION RETENTION IN_ROW ---------- ---------- ---------- ---------------- T CL 10 NO
1.3.4.4 RETENTION Parameter for BasicFiles LOBs
As an alternative to thePCTVERSIONparameter, you can specifytheRETENTIONparameter in the LOB storage clause of theCREATETABLEorALTER TABLEstatement. Doing so, configures the LOBcolumn to store old versions of LOB data for aperiod of time, rather thanusing a percentage of the table space. For example:
CREATE TABLE ContainsLOB_tab (n NUMBER, c CLOB)
lob (c) STORE AS BASICFILE segname (TABLESPACE lobtbs1 CHUNK 4096
RETENTION
NOCACHE LOGGING
STORAGE (MAXEXTENTS 5)
);
TheRETENTIONparameter is designed for use withUNDOfeatures of the database, such asFlashback Versions Query. When a LOB column has theRETENTIONproperty set, old versions of the LOB data are retainedfor the amount of time specified by theUNDO_RETENTIONparameter.
Note the following withrespect to theRETENTIONparameter:
(1)UNDOSQLis not enabled for LOB columns as it is with other data types. You must settheRETENTIONproperty on a LOB column to use Undo SQL on LOB data.
(2)You cannotset the value of theRETENTIONparameter explicitly. The amount oftime for retention of LOB versions in determined bytheUNDO_RETENTIONparameter.
--RETENTION 參數不能顯示的設置,只能通過UNDO_RETENTION 參數來繼承。
(3)Usage oftheRETENTIONparameter is only supported in Automatic UndoManagement mode. You must configure your table for use with Automatic UndoManagement before you can setRETENTIONon a LOB column.ASSM is required forLOBRETENTIONto be in effect for BasicFiles LOBs.TheRETENTIONparameter of the SQL (in theSTOREASclause)is silently ignored if the BasicFiles LOB resides in an MSSM tablespace.
(4)The LOBstorage clause can specifyRETENTIONorPCTVERSION, but notboth.
--RETENTION 和 PCTVERSION 只能設置一個。
1.3.4.5 RETENTION Parameter for SecureFiless
With 11.1 and above it is recommended to use Securefile instead of basicfiles for the LOBs. The securefiles were developed so that it will anticipate the need to move the HW mark specially with the create, insert, update of the LOBs.
Specifying theRETENTIONparameter for SecureFiless indicates that the databasemanages consistent read data for the SecureFiles storage dynamically, takinginto account factors such as theUNDOmode of the database.
(1)SpecifyMAXif the database is inFLASHBACKmode to limit the size of theLOBUNDOretention in bytes. If you specifyMAX, then you mustalso specify theMAXSIZE clause in thestorage_clause.
(2)SpecifyMINif the database is inFLASHBACKmode to limittheUNDOretention duration for the specific LOB segmenttonseconds.
(3)SpecifyAUTOifyou want to retainUNDOsufficient for consistent read purposes only.This is the default.
(4)SpecifyNONEifnoUNDOis required for either consistent read or flashback purposes.
The defaultRETENTIONfor SecureFilessisAUTO.
1.3.4.6 CACHE / NOCACHE / CACHE READS
Table 11-3 When to Use CACHE, NOCACHE, andCACHE READS
|
Cache Mode |
Read |
Write |
|
|
Frequently |
Once or occasionally |
|
|
Frequently |
Frequently |
|
|
Once or occasionally |
Never |
1.3.4.7 CACHE / NOCACHE / CACHE READS: LOB Valuesand Buffer Cache
(1)CACHE: Oracleplaces LOB pages in the buffer cache for faster access.
(2)NOCACHE: As aparameter in theSTORE ASclause,NOCACHEspecifies thatLOB values are not brought into the buffer cache.
(3)CACHE READS:LOB values are brought into the buffer cache only during read and not duringwrite operations.
NOCACHEis thedefault for both SecureFiless and BasicFiles LOBs.
Note:
Using theCACHEoption results in improved performance when reading andwriting data from the LOB column. However, it can potentially age other non-LOBpages out of the buffer cache prematurely.
1.3.4.8 LOGGING / NOLOGGING Parameter for BasicFiles LOBs
[NO]LOGGINGhasa similar application with regard to using LOBs as it does for other tableoperations. In the usual case, if the [NO]LOGGINGclause is omitted, thenthis means that neitherNOLOGGINGnorLOGGINGis specifiedand the logging attribute of the table or table partition defaults to thelogging attribute of the tablespace in which it resides.
For LOBs, there is afurther alternative depending on howCACHEis stipulated.
(1)CACHEisspecifiedand [NO]LOGGINGclause is omitted.LOGGINGisautomatically implemented (because you cannot haveCACHENOLOGGING).
(2)CACHEisnot specifiedand [NO]LOGGINGclause is omitted. The process defaultsin the same way as it does for tables and partitioned tables. That is, the[NO]LOGGINGvalue is obtained from the tablespace in which the LOB segmentresides.
當Lob數據設置為cache的時候,自動就是logging屬性。如果設置為nologging,只是lobsegment部分的數據變化不會寫redo log,不會影響到其他的in row和column列的數據redo記錄工作。
The following issues should also be kept inmind.
(1)LOBsAlways Generate Undo forLOBIndex Pages
Regardless ofwhetherLOGGINGorNOLOGGINGis set, LOBs never generaterollback information (undo) for LOB data pages because old LOB data is storedin versions. Rollback information that is created for LOBs tends to be smallbecause it is only for the LOB index page changes.
(2)WhenLOGGINGis Set Oracle Generates Full Redo forLOBData Pages
NOLOGGINGisintended to be used when a customer does not care about media recovery. Thus,if the disk/tape/storage media fails, then you cannot recover your changes fromthe log because the changes were never logged.
(3)NOLOGGING is Useful for Bulk Loads or Inserts.
For instance,when loading data into the LOB, if you do not care about redo and can juststart the load over if it fails, set the LOB data segment storagecharacteristics toNOCACHENOLOGGING. This provides good performance forthe initial load of data.
Once you havecompleted loading data, if necessary, useALTERTABLEto modifythe LOB storage characteristics for the LOB data segment for normal LOBoperations, for example, toCACHEorNOCACHELOGGING.
Note:
CACHEimplies that you also getLOGGING.
1.3.4.9 LOGGING/FILESYSTEM_LIKE_LOGGING forSecureFiless
NOLOGGINGorLOGGINGhasa similar application with regard to using SecureFilessasLOGGING/NOLOGGINGdoes for other table operations. In the usualcase, if the logging_clauseis omitted, then the SecureFiles inherits itslogging attribute from the tablespace in which it resides. In this case,ifNOLOGGINGis the default value, the SecureFiles defaultstoFILESYSTEM_LIKE_LOGGING.
Note:
UsingtheCACHEoption results in improved performance when reading andwriting data from the LOB column. However, it can potentially age other non-LOBpages out of the buffer cache prematurely.
1.3.4.10 CACHE Implies LOGGING
For SecureFiless, there is a furtheralternative depending on howCACHEis specified:
(1)CACHEisspecified and theLOGGINGclause is omitted,thenLOGGINGis used.
(2)CACHEisnot specified and the logging_clause is omitted. Then the process defaults inthe same way as it does for tables and partitioned tables. That is,theLOGGINGvalue is obtained from the tablespace in which the LOBvalue resides. If the tablespace isNOLOGGING, then the SecureFilesdefaults toFILESYSTEM_LIKE_LOGGING.
The following issues should also be kept in mind.
(1)SecureFilessand an Efficient Method of Generating REDO and UNDO
This means thatOracle Database determines if it is more efficient togenerateREDOandUNDOfor the change to a block, similarto heap blocks, or if it generates a version and full REDOof the newblock similar to BasicFiles LOBs.
(2)FILESYSTEM_LIKE_LOGGINGis Useful for Bulk Loads or Inserts
For instance,when loading data into the LOB, if you do not care aboutREDOand canjust start the load over if it fails, set the LOB data segment storagecharacteristics to FILESYSTEM_LIKE_LOGGING. This provides good performance forthe initial load of data.
Once you havecompleted loading data, if necessary, useALTERTABLEto modifythe LOB storage characteristics for the LOB data segment for normal LOBoperations. For example, toCACHEorNOCACHELOGGING.
1.3.4.11 CHUNK
A chunk is one or more Oracle blocks. You can specify the chunk size for the BasicFiles LOBwhen creating the table that contains the LOB. This corresponds to the datasize used by Oracle Database when accessing or modifying the LOB value. Part ofthe chunk is used to store system-related information and the rest stores theLOB value. The API you are using has a function that returns the amount ofspace used in the LOB chunk to store the LOB value. In PL/SQLuseDBMS_LOB.GETCHUNKSIZE. In OCI, useOCILobGetChunkSize().
Note:
If the tablespace block size is the same as the database block size,thenCHUNKis also a multiple of the database block size. The default CHUNKsize is equal to the size of onetablespace block, and the maximum value is 32K.
--chunk 默認和tablespace 的block 相等,并且最大值為32k。
(1)Choosing the Value of CHUNK
Once the valueofCHUNKis chosen (when the LOB column is created), it cannot bechanged. Hence, it is important that you choose a value which optimizes yourstorage and performance requirements. For SecureFilessCHUNKis anadvisory size and is provided for backward compatibility purposes.
Space Considerations
The valueofCHUNKdoes not matter for LOBs that are stored inline. Thishappens whenENABLESTORAGEINROWis set, and thesize of the LOB locator and the LOB data is less than approximately 4000 bytes.However, when the LOB data is stored out-of-line, it always takes up space inmultiples of theCHUNKparameter. This can lead to a large waste ofspace if your data is small, but theCHUNKis set to a large number.
Table 11-4 Data Size and CHUNK Size
|
Data Size |
CHUNK Size |
Disk Space Used to Store the LOB |
Space Utilization (Percent) |
|
3500 enable storage in row |
irrelevant |
3500 in row |
100 |
|
3500 disable storage in row |
32 KB |
32 KB |
10 |
|
3500 disable storage in row |
4 KB |
4 KB |
90 |
|
33 KB |
32 KB |
64 KB |
51 |
|
2 GB +10 |
32 KB |
2 GB + 32 KB |
99+ |
PerformanceConsiderations
Accessing lobs in big chunks is more efficient. You can setCHUNKto the data sizemost frequently accessed or written. For example, if only one block of LOB datais accessed at a time, then setCHUNKto the size of one block. Ifyou have big LOBs, and read or write big amounts of data, then choose a largevalue forCHUNK.
(2)Set INITIAL and NEXT to Larger than CHUNK
If you explicitly specify storage characteristics for the LOB, then make surethatINITIALandNEXTfor the LOB data segment storage areset to a size that is larger than the CHUNKsize. For example, if the databaseblock size is 2KB and you specify aCHUNKof 8KB, then make surethatINITIALandNEXTare bigger than 8KB and preferablyconsiderably bigger (for example, at least 16KB).
Put another way: If you specify a valueforINITIAL,NEXT, or the LOBCHUNKsize, then make surethey are set in the following manner:
CHUNK<=NEXT
CHUNK<=INITIAL
1.3.4.12 ENABLE or DISABLE STORAGE IN ROW Clause
You use theENABLE|DISABLESTORAGEINROWclauseto indicate whether the LOB should be stored inline (in the row) or out-of-line.
Note:
You may notalter this specification once you have made it: if youENABLE STORAGE INROW, then you cannot alter it toDISABLE STORAGE IN ROWand viceversa.
The defaultisENABLESTORAGEINROW.
Guidelines for ENABLE or DISABLE STORAGE IN ROW
The maximumamount of LOB data stored in the row is the maximumVARCHAR2size(4000). This includes the control information and the LOB value. If youindicate that the LOB should be stored in the row, once the LOB value andcontrol information is larger than approximately 4000, then the LOB value isautomatically moved out of the row.
This suggests thefollowing guidelines:
The default,ENABLE STORAGE IN ROW, is usually the best choice for the following reasons:
(1)Small LOBs:If the LOB is small (less than approximately 4000 bytes), then the whole LOBcan be read while reading the row without extra disk I/O.
(2)Large LOBs:If the LOB is big (greater than approximately 4000 bytes), then the controlinformation is still stored in the row if ENABLE STORAGE IN ROW is set, evenafter moving the LOB data out of the row. This control information could enableus to read the out-of-line LOB data faster.
However, in somecases DISABLE STORAGE IN ROW is a better choice. This is because storing theLOB in the row increases the size of the row. This impacts performance if youare doing a lot of base table processing, such as full table scans, multi-rowaccesses (range scans), or many UPDATE/SELECT to columns other than the LOBcolumns.
1.4 Indexing LOB Columns
This section discusses different techniquesyou can use to index LOB columns.
Note:
After you move a LOB column any existing table indexes mustbe rebuilt.
1.4.1 Using Domain Indexing on LOB Columns
You might beable to improve the performance of queries by building indexes specificallyattuned to your domain. Extensibility interfaces provided with the databaseallow for domain indexing, a framework for implementing such domain specificindexes.
Note:
You cannot builda B-tree or bitmap index on a LOB column.
1.4.2 Indexing LOB Columns Using a Text Index
Depending on the nature of the contents of the LOB column, one of the Oracle Text options couldalso be used for building indexes. For example, if a text document is stored in a CLOBcolumn, then you can build a text index to speed up the performanceof text-based queries over theCLOBcolumn.
1.4.3 Function-Based Indexes on LOBs
Afunction-based index is an index builton an expression. It extends your indexing capabilities beyond indexing on acolumn. A function-based index increases the variety of ways in which you canaccess data.
Function-basedindexes cannot be built on nested tables or LOB columns. However, you can buildfunction-based indexes on VARRAYs.
Likeextensible indexes and domain indexes on LOB columns,function-based indexes are also automatically updated when a DML operation isperformed on the LOB column. Function-based indexes are also updated when anyextensible index is updated.
1.4.4 ExtensibleIndexing on LOB Columns
The database providesextensible indexing, a feature which enables you to define new index types as required.This is based on the concept of cooperative indexing where a data cartridge and the database build and maintain indexes for data types such as text and spatialfor example, for On-line-Analytical Processing (OLAP).
The cartridge isresponsible for defining the index structure, maintaining the index contentduring load and update operations, and searching the index during queryprocessing. The index structure can be stored in Oracle as heap-organized, oran index-organized table, or externally as an operating system file.
To support this structure, the database providesanindextype. The purpose of an indextype is toenable efficient search and retrieval functions for complex domains such astext, spatial, image, and OLAP by means of a data cartridge. An indextype isanalogous to the sorted or bit-mapped index types that are built-in within theOracle Server. The difference is that an indextype is implemented by the datacartridge developer, whereas the Oracle kernel implements built-in indexes.Once a new indextype has been implemented by a data cartridge developer, endusers of the data cartridge can use it just as they would built-in indextypes.
When thedatabase system handles the physical storage of domain indexes, data cartridges
(1)Define theformat and content of an index. This enables cartridges to define an indexstructure that can accommodate a complex data object.
(2)Build,delete, and update a domain index. The cartridge handles building andmaintaining the index structures. Note that this is a significant departurefrom the medicine indexing features provided for simple SQL data types. Also,because an index is modeled as a collection of tuples, in-place updating isdirectly supported.
(3)Access andinterpret the content of an index. This capability enables the data cartridgeto become an integral component of query processing. That is, thecontent-related clauses for database queries are handled by the data cartridge.
By supportingextensible indexes, the database significantly reduces the effort needed todevelop high-performance solutions that access complex data types such as LOBs.
1.4.5 Extensible Optimizer
The extensible optimizer functionality allows authors of user-defined functions and indexes tocreate statistics collections, selectivity, and cost functions. Thisinformation is used by the optimizer in choosing a query plan. The cost-basedoptimizer is thus extended to use the user-supplied information.
Extensible indexing functionality enables you to define new operators, index types, anddomain indexes. For such user-defined operators and domain indexes, theextensible optimizer functionality allows users to control the three maincomponents used by the optimizer to select an execution plan:statistics,selectivity,andcost.
1.4.6 OracleText Indexing Support for XML
You can createOracle Text indexes onCLOBcolumns and perform queries on XML data.
1.5 Manipulating LOBs in Partitioned Tables
You canpartition tables that containLOB columns. As aresult, LOBs can take advantage of all of the benefits of partitioningincluding the following:
(1)LOB segmentscan be spread between several tablespaces to balance I/O load and to makebackup and recovery more manageable.
(2)LOBs in apartitioned table become easier to maintain.
(3)LOBs can bepartitioned into logical groups to speed up operations on LOBs that areaccessed as a group.
This section describes some of the ways you can manipulate LOBs in partitioned tables.
1.5.1 Partitioninga Table Containing LOB Columns
LOBs aresupported in RANGE partitioned, LIST partitioned, and HASH partitioned tables.Composite heap-organized tables can also have LOBs.
You can partition a tablecontaining LOB columns using the following techniques:
(1)When thetable is created using thePARTITION BY ...clause of theCREATETABLEstatement.
(2)Adding apartition to an existing table using theALTER TABLE ... ADDPARTITIONclause.
(3)Exchangingpartitions with a table that has partitioned LOB columns using theALTERTABLE ... EXCHANGE PARTITIONclause. Note thatEXCHANGEPARTITIONcan only be used when both tables have the same storageattributes, for example, both tables store LOBs out-of-line.
Creating LOBpartitions at the same time you create the table (in theCREATETABLEstatement) is recommended. If you create partitions on a LOB columnwhen the table is created, then the column can hold LOBs stored either inlineor out-of-line LOBs.
After a table iscreated, new LOB partitions can only be created on LOB columns that are storedout-of-line. Also, partition maintenance operations,SPLITPARTITIONandMERGE PARTITIONS, only work on LOB columns that storeLOBs out-of-line.
1.5.2 Creatingan Index on a Table Containing Partitioned LOB Columns
To improve the performance of queries, you can create indexes onpartitioned LOB columns. For example:
CREATE INDEX index_name
ONtable_name (LOB_column_1, LOB_column_2, ...) LOCAL;
Note that onlydomain and function-based indexes are supported on LOB columns. Other types ofindexes, such as unique indexes are not supported with LOBs.
1.5.3 Moving Partitions Containing LOBs
You can move a LOB partition into a different tablespace. This isuseful if the tablespace is no longer large enough to hold the partition. To doso, use theALTER TABLE ... MOVE PARTITIONclause. For example:
ALTER TABLE current_table MOVE PARTITION partition_name TABLESPACE destination_table_space LOB (column_name) STORE AS (TABLESPACE current_tablespace);1.5.4 SplittingPartitions Containing LOBs
You can split a partition containing LOBs into two equally sizedpartitions using theALTER TABLE ... SPLIT PARTITIONclause. Doing sopermits you to place one or both new partitions in a new tablespace. Forexample:
ALTER TABLE table_name SPLIT PARTITION partition_name AT (partition_range_upper_bound) INTO (PARTITION partition_name, PARTITION new_partition_name TABLESPACE new_tablespace_name LOB (column_name) STORE AS (TABLESPACE tablespace_name) ... ;1.5.5 Merging Partitions Containing LOBs
You can mergepartitions that contain LOB columns using theALTER TABLE ... MERGEPARTITIONSclause. This technique is useful for reclaiming unusedpartition space. For example:
ALTER TABLE table_name MERGE PARTITIONS partition_1, partition_2 INTO PARTITION new_partition TABLESPACE new_tablespace_name LOB (column_name) store as (TABLESPACE tablespace_name) ... ;1.6 LOBs in Index Organized Tables
Index OrganizedTables (IOTs) support internal and external LOB columns. For the most part, SQLDDL, DML, and piece wise operations on LOBs in IOTs produce the same results asthose for normal tables. The only exception is the default semantics of LOBsduring creation. The main differences are:
(1)TablespaceMapping: By default, or unless specified otherwise, theLOB data and index segments are created in the tablespace in which the primarykey index segments of the index organized table are created.
(2)Inlineas Compared to Out-of-Line Storage: By default, allLOBs in an index organized table created without an overflow segment are storedout of line. In other words, if an index organized table is created without anoverflow segment, then the LOBs in this table have their default storageattributes asDISABLESTORAGEINROW. If you forcibly tryto specify anENABLESTORAGEINROWclause for suchLOBs, then SQL raises an error.
On the otherhand, if an overflow segment has been specified, then LOBs in index organizedtables exactly mimic their semantics in conventional tables (see"DefiningTablespace and Storage Characteristics for Persistent LOBs").
Exampleof Index Organized Table (IOT) with LOB Columns
CREATE TABLE iotlob_tab (c1 INTEGER PRIMARY KEY, c2 BLOB, c3 CLOB, c4 VARCHAR2(20)) ORGANIZATION INDEX TABLESPACE iot_ts PCTFREE 10 PCTUSED 10 INITRANS 1 MAXTRANS 1 STORAGE (INITIAL 4K) PCTTHRESHOLD 50 INCLUDING c2 OVERFLOW TABLESPACE ioto_ts PCTFREE 10 PCTUSED 10 INITRANS 1 MAXTRANS 1 STORAGE (INITIAL 8K) LOB (c2) STORE AS lobseg (TABLESPACE lob_ts DISABLE STORAGE IN ROW CHUNK 16384 PCTVERSION 10 CACHE STORAGE (INITIAL 2M) INDEX lobidx_c1 (TABLESPACE lobidx_ts STORAGE (INITIAL 4K)));Executing thesestatements results in the creation of an index organizedtableiotlob_tabwith the following elements:
(1)A primary key index segment in thetablespaceiot_ts,
(2)An overflow data segment intablespaceioto_ts
(3)Columns starting fromcolumnC3being explicitly stored in the overflow data segment
(4)BLOB(columnC2) datasegments in the tablespacelob_ts
(5)BLOB(columnC2) indexsegments in the tablespacelobidx_ts
(6)CLOB(columnC3) datasegments in the tablespaceiot_ts
(7)CLOB(columnC3) indexsegments in the tablespaceiot_ts
(8)CLOB(columnC3) storedin line by virtue of the IOT having an overflow segment
(9)BLOB(columnC2)explicitly forced to be stored out of line
Note:
If no overflowhad been specified, then both C2 and C3 would have been stored out of line bydefault.
Other LOBfeatures, such asBFILEs and varying character width LOBs, are alsosupported in index organized tables, and their usage is the same as forconventional tables.
1.7 Restrictions for LOBs in Partitioned Index-OrganizedTables
LOB columns aresupported in range-, list-, and hash-partitioned index-organized tables withthe following restrictions:
(1)Composite partitionedindex-organized tables are not supported.
(2)Relational and object partitionedindex-organized tables (partitioned by range, hash, or list) can hold LOBsstored as follows; however, partition maintenance operations, suchasMOVE,SPLIT, andMERGEare not supported with:
1)VARRAY datatypes stored as LOB data types
2)Abstract datatypes with LOB attributes
3)Nested tableswith LOB types
1.8 Updating LOBs in Nested Tables
To update LOBsin a nested table, you must lock the row containing the LOB explicitly. To doso, you must specify the FOR UPDATE clause in the subquery prior to updatingthe LOB value.
Note thatlocking the row of a parent table does not lock the row of a nested tablecontaining LOB columns.
Note:
Nested tablescontaining LOB columns are the only data structures supported for creatingcollections of LOBs. You cannot create a VARRAY of any LOB data type.
二. LOB 說明
2.1 LOB 分類
LOB大對象主要是用來存儲大量數據的數據庫字段,在Oracle 9iR2 中LOB的最大容量是4G,Oracle 10g 最大8T,Oracle 11g 最大是128T。具體取決與blocksize 的大小。
Oracle 中支持4 種類型的LOB:
CLOB:字符LOB。這種類型用于存儲大量的文本信息,如XML 或者只是純文本。這個數據類型需要進行字符集轉換,也就是說,在獲取時,這個字段中的字符會從數據庫的字符集轉換為客戶的字符集,而在修改時會從客戶的字符集轉換為數據庫的字符集。
NCLOB:這是另一種類型的字符LOB。存儲在這一列中的數據所采用的字符集是數據庫的國家字符集,而不是數據庫的默認字符集。
BLOB:二進制LOB。這種類型用于存儲大量的二進制信息,如字處理文檔,圖像和你能想像到的任何其他數據。它不會執行字符集轉換。應用向BLOB 中寫入什么位和字節,BLOB就會返回什么為和字節。
BFILE:二進制文件LOB。這與其說是一個數據庫存儲實體,不如說是一個指針。帶BFILE列的數據庫中存儲的只是操作系統中某個文件的一個指針。這個文件在數據庫之外維護,根本不是數據庫的一部分。BFILE 提供了文件內容的只讀訪問。
LOB數據類型分類:
1.按存儲數據的類型分:
(1)字符類型:
CLOB:存儲大量單字節字符數據。
NLOB:存儲定寬多字節字符數據。
(2)二進制類型:
BLOB:存儲較大無結構的二進制數據。
(3)二進制文件類型:
BFILE:將二進制文件存儲在數據庫外部的操作系統文件中。存放文件路徑。2.按存儲方式分:
(1)存儲在內部表空間(內部LOB):
CLOB,NLOB和BLOB
(2)指向外部操作系統文件(外部LOB):
BFILE有關LOB 類型的處理,參考之前整理的Blog:
ORACLE LOB 大對象處理
http://blog.csdn.net/tianlesoftware/article/details/5070981
2.2 內部LOB
先看示例:
SQL>create user anqing identified by anqing;
SQL>grant connect,resource,dba to anqing;
SYS@anqing1(rac1)> conn anqing/anqing;
Connected.
ANQING@anqing1(rac1)> create table tl(idnumber primary key,txt clob);
Table created.
TL 表的創建腳本如下:
SQL>selectdbms_metadata.get_ddl( 'TABLE','TL')fromdual; /* Formatted on 2011/10/2511:26:26 (QP5 v5.163.1008.3004) */ CREATE TABLE"ANQING"."TL" ( "ID" NUMBER, "TXT" CLOB, PRIMARYKEY ("ID") USINGINDEXPCTFREE10 INITRANS2 MAXTRANS255 STORAGE(INITIAL65536 NEXT1048576 MINEXTENTS1 MAXEXTENTS2147483645 PCTINCREASE0 FREELISTS 1 FREELISTGROUPS1 BUFFER_POOLDEFAULT) TABLESPACE"USERS" ENABLE ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE (INITIAL65536 NEXT 1048576 MINEXTENTS1 MAXEXTENTS2147483645 PCTINCREASE0 FREELISTS1 FREELISTGROUPS1 BUFFER_POOLDEFAULT) TABLESPACE "USERS" LOB ( "TXT") STOREAS ( TABLESPACE"USERS" ENABLESTORAGEINROW CHUNK8192 PCTVERSION10 NOCACHELOGGING STORAGE(INITIAL65536 NEXT1048576 MINEXTENTS1 MAXEXTENTS2147483645 PCTINCREASE0 FREELISTS1 FREELISTGROUPS1 BUFFER_POOLDEFAULT)) ANQING@anqing1(rac1)> set wrap off; ANQING@anqing1(rac1)> col segment_namefor a35 ANQING@anqing1(rac1)> selectsegment_name, segment_type from user_segments; SEGMENT_NAME SEGMENT_TYPE ----------------------------------------------------- SYS_C007307 INDEX SYS_IL0000056466C00002$ LOBINDEX SYS_LOB0000056466C00002$ LOBSEGMENT TL TABLESYS_C007307索引用來支持主鍵約束,lobindex 和lobsegment是為了支持我們的LOB 列。我們的實際LOB 數據就存儲在lobsegment 中( 確實,LOB 數據也有可能存儲在表T 中,不過稍后討論ENABLE STORAGE IN ROW 子句時還會更詳細地說明這個內容)。lobindex 用于執行LOB 的導航,來找出其中的某些部分。創建一個LOB 列時,一般來說,存儲在行中的這是一個指針(pointer),或LOB 定位器(LOB locator)。我們的應用所獲取的就是這個LOB 定位器。
當請求得到LOB 的“12.000~2,000 字節”時,將對lobindex 使用LOB 定位器來找出這些字節存儲在哪里,然后再訪問lobsegment。可以用lobindex 很容易地找到LOB 的各個部分。由此說來,可以把LOB想成是一種主/明細關系。
LOB 按“塊”(chunk)或(piece)來存儲,每個片段都可以訪問。例如,如果我們使用表來實現一個LOB,可以如下做到這一點:
/* Formatted on 2011/10/2510:51:00 (QP5 v5.163.1008.3004) */ CREATE TABLEparent ( id INT PRIMARYKEY, other data... ); CREATE TABLElob ( id REFERENCESparentONDELETECASCADE, chunk_number INT, data <datatype>(n), primary key(id,chunk_number) );從概念上講,LOB 的存儲與之非常相似,創建這兩個表時,在LOB 表的ID.CHUNK_NUMBER上要有一個主鍵(這對應于Oracle創建的lobindex),而且要有一個LOB 表來存儲數據塊(對應于lobsegment)。LOB列為我們透明地實現了這種主/明細結構。
為了得到LOB 中的N~M字節,要對表中的指針(LOB 定位器)解除引用,遍歷lobindex 結構來找到所需的數據庫(chunk), 然后按順序訪問。這使得隨機訪問LOB 的任何部分都能同樣迅速,你可以用同樣快的速度得到LOB 的最前面、中間或最后面的部分,因為無需再從頭開始遍歷LOB。
2.2.1. LOB 表空間
CREATE TABLE 語句包括以下內容:
LOB(TXT)STOREAS(TABLESPACEUSERS…
這里指定的TABLESPACE 是將存儲lobsegment 和lobindex 表空間,這可能與表本身所在的表空間不同。也就是說,保存LOB 數據的表空間可能不同于保存實際表數據的表空間。
為什么考慮為LOB 數據使用另外一個表空間(而不用表數據所在的表空間)呢?注意原因與管理和性能有關。從管理的角度看,LOB 數據類型表示一種規模很大的信息。如果表有數百萬行,而每行有一個很大的LOB,那么LOB 就會極為龐大。為LOB 數據單獨使用一個表空間有利于備份和恢復以及空間管理,單從這一點考慮,將表與LOB 數據分離就很有意義。例如,你可能希望LOB 數據使用另外一個統一的區段大小,而不是普通表數據所用的區段大小。
另一個原因則出于I/O 性能的考慮。默認情況下,LOB 不在緩沖區緩存中進行緩存(有關內容將在后面再做說明)。因此,默認情況下,對于每個LOB 訪問,不論是讀還是寫,都會帶來一個物理I/O(從磁盤直接讀,或者向磁盤直接寫)。
注意: LOB 可能是內聯的(inline),或者存儲在表中。在這種情況下,LOB 數據會被緩存,但是這只適用于小于4,000 字節的LOB。我們將在“IN ROW 子句”一節中進一步討論這種情況。
由于每個訪問都是一個物理I/O,所以如果你很清楚在實際中(當用戶訪問時)有些對象會比大多數其他對象經歷更多的物理I/O,那么將這些對象分離到它們自己的磁盤上就很有意義。
需要說明,lobindex 和lobsegment 總是會在同一個表空間中。不能將lobindex 和lobsegment 放在不同的表空間中。在Oralce 的更早版本中,允許為lobindex 和lobsegment 分別放在單獨的表空間中,但是從8i Release 3 以后,就不再允許為lobindex 和logsegment 指定不同的表空間。實際上,lobindex的所有存儲特征都是從lobsegment 繼承的。
2.2.2. IN ROW 子句
CREATE TABLE 語句還包括以下內容:
LOB(TXT)STOREAS(…ENABLESTORAGEINROW…
這控制了LOB 數據是否總與表分開存儲(存儲在lobsegment 中),或是有時可以與表一同存儲,而不用單獨放在lobsegment 中。如果設置了ENABLE STORAGE IN ROW,而不是DISABLE STORAGE IN ROW,小LOB(最多4,000 字節)就會像VARCHAR2 一樣存儲在表本身中。只有當LOB 超過了4,000 字節時,才會“移出”到lobsegment 中。
默認行為是啟用行內存儲(ENABLE STORAGEIN ROW),而且一般來講,如果你知道LOB 總是能在表本身中放下,就應該采用這種默認行為。例如,你的應用可能有一個某種類型的DESCRIPTION 字段。這個DESCRIPTION 可以存儲0~32KB 的數據(或者可能更多,但大多數情況下都少于或等于32KB)。已知很多描述都很簡短,只有幾百個字符。如果把它們單獨存儲,并在每次獲取時都通過索引來訪問,就會存在很大的開銷,你完全可以將它們內聯存儲,即放在表本身中,這就能避免單獨存儲的開銷。不僅如此,如果LOB還能避免獲取LOB 時所需的物理I/O。
一般來說,OUT ROW,即將數據存儲在segment里,在這種情況下不會在buffer cache 中進行緩存,這樣每次都會產生物理IO. 同時對out row 進行讀寫操作時,雖然有lobindex的存在,但 DML 操作需要同時維護lobindex和lobsegment。 采用OUT ROW 會增加邏輯IO和物理IO,所以默認啟用IN ROW。 對lob 進行緩存,減小IO成本。
2.2.3. CHUNK 子句
CREATE TABLE 語句包括以下內容:
LOB("TXT") STORE AS ( ... CHUNK 8192 ... )
LOB 存儲在塊(chunk)中,指向LOB 數據的索引會指向各個數據塊。塊(chunk)是邏輯上連續的一組數據庫塊(block),這也是LOB 的最小分配單元,而通常數據庫的最小分配單元是數據庫塊。CHUNK 大小必須是Oracle 塊大小的整數倍,只有這樣才是合法值。
從兩個角度看,選擇CHUNK 大小時必須當心。首先,每個LOB實例(每個行外存儲的LOB 值)會占用至少一個CHUNK。一個CHUNK 有一個LOB 值使用。如果一個表有100 行,而每行有一個包含7KB 數據的LOB,你就會分配100 個CHUNK,如果將CHUNK 大小設置為32KB,就會分配100 個32KB 的CHUNK。如果將CHUNK大小設置為8KB,則(可能)分配100 個8KB 的CHUNK。關鍵是,一個CHUNK 只能有一個LOB 使用(兩個LOB 不會使用同一個CHUNK)。如果選擇了一個CHUNK 大小,但不符合你期望的LOB 大小,最后就會浪費大量的空間。例如,如果表中的LOB 平均有7KB,而你使用的CHUNK 大小為32KB,對于每個LOB 實例你都會“浪費”大約25KB 的空間,另一方面,倘若使用8KB 的CHUNK,就能使浪費減至最少。
還需要注意要讓每個LOB 實例相應的CHUNK 數減至最少。前面已經看到了,有一個lobindex 用于指向各個塊,塊越多,索引就越大。如果有一個4MB 的LOB,并使用8KB 的CHUNK,你就至少需要512 個CHUNK來存儲這個消息。這也說明,至少需要512 個lobindex 條目指向這些CHUNK。聽上去好像沒什么,但是你要記住,對于每個LOB 個數的512 倍。另外,這還會影響獲取性能,因為與讀取更少但更大的CHUNK 相比,現在要花更長的數據來讀取和管理許多小CHUNK。我們最終的目標是:使用一個能使“浪費”最少,同時又能高效存儲數據的CHUNK大小。
2.2.4. PCTVERSION 子句
DBMS_METADATA 返回的CREATE TABLE 語句包括以下內容:
LOB("TXT") STORE AS ( ... PCTVERSION 10. ... )
多版本一致讀、當前讀是Oracle數據庫具有的獨特屬性,也是其最重要的特性之一。借助undo表空間的前鏡像數據保存,OracleServerProcess可以訪問到一些特定時間點(SCN)的數據,作為一致性讀取、免于臟數據。
但對于Lob類型而言,一致讀問題同樣存在。Oracle需要一種保留Lob數據鏡像的機制,保存一系列old version。目前,Oracle提供了兩種維持機制來進行控制:基于時間的版本保留retention和基于空間的版本保留pctversion。
SQL> select table_name, column_name,pctversion, retention from user_lobs; TABLE_NAME COLUMN_NAMPCTVERSION RETENTION ---------- ---------- ---------- ---------- T CL 900LOB在lobsegment 中保留某個百分比的空間來實現LOB 的版本化,直接在lobsegment 本身中維護信息的版本。lobindex 會像其他段一樣生成undo,但是lobsegment 不會。
相反,修改一個LOB 時,Oracle 會分配一個新的CHUNK,并且仍保留原來的CHUNK。如果回滾了事務,對LOB 索引所做的修改會回滾,索引將再次指向原來的CHUNK。因此,undo 維護會在LOB 段本身中執行。修改數據時,原來的數據庫保持不動,此外會創建新數據。
讀LOB 數據時這也很重要。LOB 是讀一致的,這與所有其他段一樣。如果你在上午9:00 獲取一個LOB定位器,你從中獲取的LOB 數據就是“上午9:00 那個時刻的數據”。這就像是你在上午9:00 打開了一個游標(一個結果集)一樣,所生成的行就是那個時間點的數據行。與結果集類似,即使別人后來修改了LOB數據。在此,Oracle 會使用lobsegment,并使用logindex 的讀一致視圖來撤銷對LOB 的修改,從而提取獲取LOB 定位器當時的LOB 數據。它不會使用logsegment 的undo 信息,因為根本不會為logsegment 本身生成undo 信息。
PCTVERSION 控制著用于實現LOB 數據版本化的已分配LOB 空間的百分比(這些數據庫塊由某個時間點的LOB 所用,并處在lobsegment 的HWM 以下)。對于許多使用情況來說,默認設置10%就足夠了,因為在很多情況下,你只是要INSERT 和獲取LOB(通常不會執行LOB 的更新;LOB 往往會插入一次,而獲取多次)。因此,不必為LOB 版本化預留太多的空間(甚至可以沒有)。
不過,如果你的應用確實經常修改LOB,倘若你頻繁地讀LOB,與此同時另外某個會話正在修改這些LOB,10%可能就太小了。如果處理LOB 時遇到一個ORA-22924錯誤,解決方案不是增加undo表空間的大小,也不是增加undo保留時間(UNDO_RETENTION),如果你在使用手動undo 管理,那么增加更多RBS 空間也不能解決這個問題。而是應該使用以下命令:
ALTER TABLEtabname MODIFY LOB (lobname) ( PCTVERSION n );
并增加lobsegment 中為實現數據版本化所用的空間大小。
2.2.5. RETENTION 子句
Retention是表示采用基于時間版本保留策略。簡單的說,就是盡量保證保留一個時間段內的數據lob版本不會清除掉,即多長時間內來保證一致讀。在數據庫版本的兼容性版本設置在9.2.0.0以上,并且undo_management參數值為true時,lob是默認直接使用retetion設置的。
需要注意,不能使用這個子句來指定保留時間;而要從數據庫的UNDO_RETENTION 設置來繼承它。
這個子句與PCTVERSION 子句是互斥的,即RETENTION和 PCTVERSION 只能設置一個,不能兩個都設置。
2.2.6. CACHE 子句
前面的DBMS_METADATA返回的CREATETABLE 語句包括以下內容:
LOB("TXT") STORE AS (... NOCACHE ... )
除了NOCACHE,這個選項還可以是CACHE 或CACHE READS。這個子句控制了lobsegment 數據是否存儲在緩沖區緩存中。默認的NOCACHE 指示,每個訪問都是從磁盤的一個直接讀,類似地,每個寫/修改都是對大盤的一個直接寫。CACHE READS 允許緩存從磁盤讀的LOB 數據,但是LOB 數據的寫操作必須直接寫至磁盤。CACHE 則允許讀和寫時都能緩存LOB 數據。
在許多情況下,默認設置可能對我們并不合適。如果你只有小規模或中等規模的L O B(例如,使用LOB來存儲只有幾KB 的描述性字段),對其緩存就很有意義。如果不緩存,當用戶更新描述字段時,還必須等待I/O 將數據寫指磁盤(將執行一個CHUNK大小的I/O,而且用戶要等待這個I/O 完成)。如果你在執行多個LOB 的加載,那么加載每一行時都必須等待這個I/O 完成。所以啟用執行LOB 緩存很合理。你可以打開和關閉緩存,來看看會有什么影響:
ALTER TABLEtabname MODIFY LOB (lobname) ( CACHE );
ALTER TABLEtabname MODIFY LOB (lobname) ( NOCACHE );
對于一個規模很多的初始加載,啟用LOB 的緩存很有意義,這允許DBWR在后臺將LOB 數據寫至磁盤,而你的客戶應用可以繼續加載更多的數據。對于頻繁訪問或修改的小到中等規模的LOB,緩存就很合理,可以部門讓最終用戶實時等待物理I/O 完成。不過,對于一個大小為50MB的LOB,把它放在緩存中就沒帶道理了。
要記住,此時可以充分使用Keep 池或回收池。并非在默認緩存中將lobsegment 數據與所有“常規”數據一同緩存,可以使用保持池或回收池將其分開緩存。采用這種方式,既能緩存LOB 數據,而且不影響系統中現有數據的緩存。
2.2.7. LOB STORAGE 子句
DBMS_METADATA 返回的CREATE TABLE 語句還包括以下內容:
LOB ("TXT") STORE AS (… STORAGE(INITIAL65536 NEXT1048576 MINEXTENTS1 MAXEXTENTS2147483645 PCTINCREASE0 FREELISTS1 FREELISTGROUPS1 BUFFER_POOLDEFAULT))也就是說,它有一個完整的存儲子句,可以用來控制物理存儲特征。需要指出,這個存儲子句同樣適用于lobsegment 和lobindex,對一個段的設置也可以用于另一個段。假設有一個本地管理的表空間,LOB的相關設置將是FREELISTS、FREELIST GROUPS 和BUFFER_POOL。
對LOB 段使用保持池或回收池可能是一個很有用的技術,這樣就能緩存LOB 數據,而且不會“破壞”現有的默認緩沖區緩存。并不是將LOB 與常規表一同放在塊緩沖區中,可以在SGA 中專門為這些LOB 對象預留一段專用的內存。BUFFER_POOL 子句可以達到這個目的。
2.3 BFILE
BFILE 類型只是操作系統上一個文件的指針。它用于為這些操作系統文件提供只讀訪問。
注意: 內置包UTL_FILE 也為操作系統文件提供了讀寫訪問。不過它沒有使用BFILE 類型。
使用BFILE 時,還有使用一個Oracle DIRECTORY 對象。DIRECTORY 對象只是將一個操作系統目錄映射至數據庫中的一個“串”或一個名稱(以提供可移植性;你可能想使用BFILE 中的一個串,而不是操作系統特定的文件名約定)。
作為一個小例子,下面創建一個帶BFILE 列的表,并創建一個DIRECTORY對象,再插入一行,其中引用了文件系統中的一個文件:
SQL> create table t ( id int primarykey,os_file bfile); Table created. SQL> create or replace directory my_diras '/tmp/'; Directory created. SQL> insert into t values ( 1,bfilename( 'MY_DIR', 'test.dbf' ) ); 12.row created.現在,就可以把BFILE 當成一個LOB 來處理,因為它就是一個LOB。例如,我們可以做下面的工作:
SQL> select dbms_lob.getlength(os_file)from t; DBMS_LOB.GETLENGTH(OS_FILE) --------------------------- 1056768可以看到所指定的文件大小為1MB。注意,這里故意在INSERT語句中使用了MY_DIR。如果使用混合大小寫或小寫,會得到以下錯誤:
SQL> update t set os_file = bfilename('my_dir', 'test.dbf' ); 12.row updated. SQL> select dbms_lob.getlength(os_file)from t; select dbms_lob.getlength(os_file) from t * ERROR at line 1: ORA-22285: non-existent directory or filefor GETLENGTH operation ORA-06512: at "SYS.DBMS_LOB",line 566這個例子只是說明:Oracle 中的DIRECTORY 對象是標識符,而默認情況下標識符都以大寫形式存儲。
BFILENAME 內置函數接受一個串,這個串的大小寫必須與數據字典中存儲的DIRECTORY對象的大小寫完全匹配。所以,我們必須在BFILENAME 函數中使用大寫,或者在創建DIRECTORY 對象時使用加引號的標識符:
SQL> create or replace directory"my_dir" as '/tmp/'; Directory created. SQL> select dbms_lob.getlength(os_file)from t; DBMS_LOB.GETLENGTH(OS_FILE) --------------------------- 1056768不建議使用加引號的標識符;而傾向于在BFILENAME 調用中使用大寫。加引號的標識符屬于“異類”,可能會在以后導致混淆。
BFILE 在磁盤上占用的空間不定,這取決于DIRECTORY 對象名的文件名的長度。在前面的例子中,所得到的BFILE 長度大約為35 字節。一般來說,BFILE 會占用大約20 字節的開銷,再加上DIRECTORY 對象的長度以及文件名本身的長度。
與其他LOB 數據不同,BFILE 數據不是“讀一致”的。由于BFILE 在數據庫之外管理,對BFILE 解除引用時,不論文件上發生了什么,都會反映到你得到的結果中。所以,如果反復讀同一個BFILE,可能會產生不同的結果,這與對CLOB、BLOB 或NCLOB 使用LOB 定位器不同。
三. Move Table 與 LOB
在之前的Blog:
Oracle 高水位(HWM: High Water Mark) 說明
http://blog.csdn.net/tianlesoftware/article/details/4707900
提到解決高水位的一種方法就是Move Table,如果我們的表里有LOB 字段,那么我們在Move 的時候就需要注意一下。
在建立含有lob字段的表時,oracle會自動為lob字段建立兩個單獨的segment,一個用來存放數據(segment_type=LOBSEGMENT),另一個用來存放索引(segment_type=LOBINDEX)。
我們對表MOVE時,LOG類型字段和該字段的索引不會跟著MOVE,必須要單獨來進行MOVE,語法如下如:
SQL>altertable owner.table_name move tablespace tablespace_name lob (lob_column) store as (tablespace tablespace_name);
也可以分2部來走:
SQL> altertable owner.table_name move tablespace tablespace_name;
SQL>altertable owner.table_name move lob(lob_column) store as (tablespacetablespace_name) ;
Move操作會導致表上的索引失效,操作結束后我們需要對索引進行rebuild。這部分可以參考我的Blog:
Oracle alter index rebuild 說明
http://blog.csdn.net/tianlesoftware/article/details/6538928
四. 含有LOB 字段表的遷移示例
這里演示2個不同用戶之間的一個遷移,使用expdp/impdp 來實現,有關data pump 參考:
Oracle expdp/impdp 使用示例
http://blog.csdn.net/tianlesoftware/article/details/6260138
1.先創建directory:
SQL> create directory backup as'/u01/backup'; Directory created. SQL> select * from dba_directories; OWNERDIRECTORY_NAME DIRECTORY_PATH ----- ------------------------------------------------------------------------- SYS BACKUP /u01/backup2.創建2個測試用的用戶,每個用戶有獨立的表空間。
SQL>CREATE TABLESPACEanqing1 DATAFILE '+DATA/anqing/datafile/anqing01.dbf' SIZE 200M AUTOEXTEND OFF; SQL>CREATE TABLESPACEanqing2 DATAFILE '+DATA/anqing/datafile/anqing02.dbf' SIZE 200M AUTOEXTEND OFF; SQL>create useranqing1 identified by anqing1 default tablespace anqing1; SQL>create useranqing2 identified by anqing2 default tablespace anqing1; SQL>grant connect,resource,dba toanqing1,anqing2;3.登陸anqing1 用戶,創建含有LOB的表:
SYS@anqing1(rac1)> conn anqing1/anqing1; Connected. ANQING1@anqing1(rac1)> create table lob1(line number,text clob); Table created. ANQING1@anqing1(rac1)> insert into lob1 select line,text from all_source; 302179 rows created. ANQING1@anqing1(rac1)> select segment_name,segment_type,tablespace_name,sum(bytes)/1024/1024||'M'as "SIZE" from user_segments group by segment_name,segment_type,tablespace_name; SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME SIZE ------------------------------------------------ --------------- -------------- SYS_LOB0000056470C00002$ LOBSEGMENT ANQING1 27M LOB1 TABLE ANQING1 44M SYS_IL0000056470C00002$ LOBINDEX ANQING1 .0625M這里我們可以看到,我的表LOB1占用空間44M,LOBSEGMENT 占用27M。
4.采用REMAP_SCHEMA
4.1 expdp 導出:
[oracle@rac1 backup]$expdp anqing1/anqing1 directory=backup dumpfile=anqing1.dmp logfile=anqing1.log schemas=anqing1; Export: Release 10.2.0.4.0 - Production onTuesday, 25 October, 2011 20:52:24 Copyright (c) 2003, 2007, Oracle. All rights reserved. Connected to: Oracle Database 10gEnterprise Edition Release 10.2.0.4.0 - Production With the Partitioning, Real ApplicationClusters, OLAP, Data Mining and Real Application Testing options FLASHBACK automatically enabled to preservedatabase integrity. Starting"ANQING1"."SYS_EXPORT_SCHEMA_01": anqing1/******** directory=backupdumpfile=anqing1.dmp logfile=anqing1.log schemas=anqing1 Estimate in progress using BLOCKS method... Processing object typeSCHEMA_EXPORT/TABLE/TABLE_DATA Total estimation using BLOCKS method: 71 MB Processing object type SCHEMA_EXPORT/USER Processing object typeSCHEMA_EXPORT/SYSTEM_GRANT Processing object typeSCHEMA_EXPORT/ROLE_GRANT Processing object typeSCHEMA_EXPORT/DEFAULT_ROLE Processing object typeSCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA Processing object typeSCHEMA_EXPORT/TABLE/TABLE Processing object typeSCHEMA_EXPORT/TABLE/INDEX/INDEX Processing object typeSCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT Processing object typeSCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS Processing object typeSCHEMA_EXPORT/TABLE/COMMENT . . exported"ANQING1"."LOB1" 51.10 MB 302179 rows Master table"ANQING1"."SYS_EXPORT_SCHEMA_01" successfullyloaded/unloaded ****************************************************************************** Dump file set forANQING1.SYS_EXPORT_SCHEMA_01 is: /u01/backup/anqing1.dmp Job"ANQING1"."SYS_EXPORT_SCHEMA_01" successfully completed at20:53:064.2 impdp 導入:
[oracle@rac1 backup]$impdp anqing2/anqing2 directory=backupdumpfile=anqing1.dmp logfile=anqing2.log remap_schema=anqing1:anqing2 table_exists_action=replace; Import: Release 10.2.0.4.0 - Production onTuesday, 25 October, 2011 20:56:15 Copyright (c) 2003, 2007, Oracle. All rights reserved. Connected to: Oracle Database 10gEnterprise Edition Release 10.2.0.4.0 - Production With the Partitioning, Real ApplicationClusters, OLAP, Data Mining and Real Application Testing options Master table"ANQING2"."SYS_IMPORT_FULL_01" successfully loaded/unloaded Starting"ANQING2"."SYS_IMPORT_FULL_01": anqing2/******** directory=backupdumpfile=anqing1.dmp logfile=anqing2.log remap_schema=anqing1:anqing2table_exists_action=replace Processing object type SCHEMA_EXPORT/USER ORA-31684: Object typeUSER:"ANQING2" already exists Processing object typeSCHEMA_EXPORT/SYSTEM_GRANT Processing object typeSCHEMA_EXPORT/ROLE_GRANT Processing object typeSCHEMA_EXPORT/DEFAULT_ROLE Processing object typeSCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA Processing object typeSCHEMA_EXPORT/TABLE/TABLE Processing object typeSCHEMA_EXPORT/TABLE/TABLE_DATA . . imported"ANQING2"."LOB1" 51.10 MB 302179 rows Job"ANQING2"."SYS_IMPORT_FULL_01" completed with 1 error(s) at20:57:414.3 驗證:
ANQING1@anqing1(rac1)> connanqing2/anqing2; Connected. ANQING2@anqing1(rac1)> col segment_namefor a30 ANQING2@anqing1(rac1)> coltablespace_name for a15 ANQING2@anqing1(rac1)> selectsegment_name,segment_type,tablespace_name,sum(bytes)/1024/1024||'M' as"SIZE" from user_segments group by segment_name,segment_type,tablespace_name; SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME SIZE ------------------------------ --------------------------------- -------------- LOB1 TABLE ANQING1 44M SYS_IL0000056648C00002$ LOBINDEX ANQING1 .0625M SYS_LOB0000056648C00002$ LOBSEGMENT ANQING1 27M ANQING2@anqing1(rac1)> select owner,table_name,tablespace_name fromall_tables where table_name ='LOB1'; OWNER TABLE_NAME TABLESPACE_NAME ------------------------------------------------------------ --------------- ANQING2 LOB1 ANQING1 ANQING1 LOB1 ANQING1我們的數據已經導入到了anqing2用戶下,但是該表的物理存儲還是存在anqing1的tablespace下面。
4.4 Move Table
將LOB1從anqing1 表空間下面Move 到anqing2下面。
ANQING2@anqing1(rac1)> alter table LOB1move tablespace anqing2; Table altered. 驗證: ANQING2@anqing1(rac1)> selectsegment_name,segment_type,tablespace_name,sum(bytes)/1024/1024||'M' as"SIZE" from user_segments group by segment_name,segment_type,tablespace_name; SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME SIZE ------------------------------------------------ --------------- -------------- SYS_LOB0000056739C00002$ LOBSEGMENT ANQING1 27M LOB1 TABLE ANQING2 44M SYS_IL0000056739C00002$ LOBINDEX ANQING1 .0625M 9.867 TEMPORARY ANQING1 44M 9.883 TEMPORARY ANQING1 .0625M這里的LOB1 表已經移到anqing2的表空間下了,但是LOBSEGMENT和LOBINDEX 還沒有移動。 繼續操作:
ANQING2@anqing1(rac1)> alter table lob1move lob(text) store as (tablespace anqing2) ; Table altered. ANQING2@anqing1(rac1)> selectsegment_name,segment_type,tablespace_name,sum(bytes)/1024/1024||'M' as"SIZE" from user_segments group by segment_name,segment_type,tablespace_name; SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME SIZE ------------------------------------------------ --------------- -------------- LOB1 TABLE ANQING2 44M SYS_LOB0000056739C00002$ LOBSEGMENT ANQING2 27M SYS_IL0000056739C00002$ LOBINDEX ANQING2 .0625M 9.867 TEMPORARY ANQING1 44M 9.883 TEMPORARY ANQING1 .0625M我這里演示的是不同用戶之間的一個遷移,如果是相同用戶下的遷移,只需要在操作之前把相關的表空間和用戶建好就可以了。
注:第二小結內容出自:<Oracle 9i/10g 編程藝術>
-------------------------------------------------------------------------------------------------------
版權所有,文章允許轉載,但必須以鏈接方式注明源地址,否則追究法律責任!
Blog: http://blog.csdn.net/tianlesoftware
Weibo: http://weibo.com/tianlesoftware
Email: tianlesoftware@gmail.com
Skype: tianlesoftware
-------加群需要在備注說明Oracle表空間和數據文件的關系,否則拒絕申請----
DBA1 群:62697716(滿); DBA2 群:62697977(滿)DBA3 群:62697850(滿)
DBA 超級群:63306533(滿); DBA4 群:83829929(滿) DBA5群: 142216823(滿)
DBA6 群:158654907(滿) DBA7 群:69087192(滿)DBA8 群:172855474
DBA 超級群2:151508914 DBA9群:102954821 聊天 群:40132017(滿)
道森Oracle,國內最早、最大的網絡語音培訓機構,我們提供專業、優質的Oracle技術培訓和服務!
我們的官方網站:http://www.daosenoracle.com
官方淘寶店:http://daosenpx.taobao.com/總結
以上是生活随笔為你收集整理的Oracle LOB 详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Pygame详解:font 模块
- 下一篇: k8s中的PKI证书