Oracle9i Application Developer's Guide - Large Objects (LOBs) Release 2 (9.2) Part Number A96591-01 |
|
This chapter discusses the following topics:
You can use SQL*Loader to bulk load LOBs.
See:
|
Because LOBs can be quite large, SQL*Loader can load LOB data from either the main datafile (inline with the rest of the data) or from LOBFILEs. Figure 9-1 shows the LOBFILE syntax.
Text description of the illustration apa30.gif
LOB data can be lengthy enough that it makes sense to load it from a LOBFILE. In LOBFILEs, LOB data instances are still considered to be in fields (predetermined size, delimited, length-value), but these fields are not organized into records (the concept of a record does not exist within LOBFILEs). Therefore, the processing overhead of dealing with records is avoided. This type of organization of data is ideal for LOB loading.
There is no requirement that a LOB from a LOBFILE fit in memory. SQL*Loader reads LOBFILEs in 64K chunks. To load physical records larger than 64K, you can use the READSIZE parameter to specify a larger size.
It is best to load XMLType columns or columns containing XML data in CLOBs, using LOBFILEs.
A conventional path load executes SQL INSERT statements to populate tables in an Oracle database. A direct path load eliminates much of the Oracle database overhead by formatting Oracle data blocks and writing the data blocks directly to the database files.
A direct-path load does not compete with other users for database resources, so it can usually load data at near disk speed. Considerations inherent to direct path loads, such as restrictions, security, and backup implications, are discussed in Chapter 9 of Oracle9i Database Utilities.
Figure 9-2 illustrates SQL*Loader's direct-path load and conventional path loads.
Tables to be loaded must already exist in the database. SQL*Loader never creates tables. It loads existing tables that either already contain data or are empty.
The following privileges are required for a load:
See Also:
Oracle9i Database Utilities for more information on: loading objects, LOBs, and Collections; and SQL*Loader case studies. |
Text description of the illustration sutil018.gif
Use the following guidelines to achieve maximum performance with LOBs:
LOB
s are big, you can obtain the best performance by reading and writing large chunks of a LOB
value at a time. This helps in several respects:
LOB
from the client side and the client is at a different node than the server, large reads/writes reduce network overhead.NOCACHE
' option, each small read/write incurs an I/O. Reading/writing large quantities of data reduces the I/O.LOB
creates a new version of the LOB
CHUNK
. Therefore, writing small amounts at a time will incur the cost of a new version for each small write. If logging is on, the CHUNK
is also stored in the redo log.LOB
data on the client, use LOB
buffering -- see OCILobEnableBuffering
(), OCILobDisableBuffering
(), OCILobFlushBuffer
(), OCILobWrite
(), OCILobRead
(). Basically, turn on LOB
buffering before reading/writing small pieces of LOB
data.
See Also:
Chapter 5, "Large Objects: Advanced Topics", "LOB Buffering Subsystem" for more information on |
LOB
. Ensure the length of the entire write is set in the 'amount
' parameter on input. Whenever possible, read and write in multiples of the LOB
chunk size.LOB
s are optimized for the following operations:
See Also:
Chapter 7, "Modeling and Design", "Performance Attributes When Using SQL Semantics with LOBs" , for information about performance issues when using SQL semantics with LOBs |
Table 9-1 lists the results of a performance test that enqueued 500 messages using a chunk size of 8KB for the LOB part of the payload. This performance test used Oracle8i Release 3 (8.1.7), and a DB_BLOCKSIZE = 8192 (8K), identical to the operating system block size.
Previous response times using a 16k chunksize, NOCACHE, and NOLOGGING for a message of 4000 bytes was 12:28 sec.
These results indicate that the CACHE parameter is the parameter giving the best performance improvement.
In addition to the guidelines described earlier under "LOB Performance Guidelines" on LOB performance in general, here are some guidelines for using temporary LOBs:
If you use the newly provided enhanced SQL semantics functionality in your applications, there will be many more temporary LOBs created silently in SQL and PL/SQL than before. Ensure that temporary tablespace for storing these temporary LOBs islarge enough for your applications. In particular, these temporary LOBs are silently created when you use the following:
This is because, by using a package variable which persists in a session, allocating extra memory to manage temporary LOBs in every procedure call is avoided.
CREATE OR REPLACE PACKAGE pk is tmplob clob; END pk; / CREATE OR REPLACE PROCEDURE temp_lob_proc IS BEGIN -- instead of using a local LOB variabe, use a package variable here DBMS_LOB.CREATETEMPORARY(pk.tmplob, TRUE); -- Do some LOB data maniputation here DBMS_LOB.FREETEMPORARY(pk.tmplob); END; / DECLARE doc CLOB; BEGIN FOR i IN 1..400 LOOP temp_lob_proc(); END LOOP; END; /
LOCATOR1 BLOB; LOCATOR2 BLOB; DBMS_LOB.CREATETEMPORARY (LOCATOR1,TRUE,DBMS_LOB.SESSION); LOCATOR2 := LOCATOR;
This code causes a copy of the temporary LOB pointed to by LOCATOR1 to be created. When passing temporary LOB parameters to procedures or functions, you might also want to consider using pass by reference semantics in PL/SQL.
In OCI, to ensure copy semantics of LOB locators and data, OCILobLocatorAssign is used to copy temporary LOB locators as well as the LOB data. To avoid the deep copy, pointer assignment can be done, if copy semantics of locator copy is not intended. For example:
OCILOBLocator *LOC1; OCILOBLocator *LOC2; OCILOBCREATETEMPORARY (LOC1,TRUE,OCIDURATIONSESSION); LOC2 = LOC1;
To improve the performance of temporary LOBs on LOB assignment, use OCI_OBJECT mode for OCILobLocatorAssign. In the OCI_OBJECT mode, Oracle tries to minimize the number of deep copies to be done. Hence, after OCILobLocatorAssign is done on a source temporary LOB in OCI_OBJECT mode, the source and the destination locators will point to the same LOB until any modification is made through either LOB locator.
In PL/SQL, C (OCI), Java and other programmatic interfaces, SQL query results or PLSQL program executions return temporary LOBs for operation/function calls on LOBs. For example:
SELECT substr(CLOB_Column, 4001, 32000) FROM ...
If the query is executed in PLSQL, the returned temporary LOBs automatically get freed at the end of a PL/SQL program block. You can also explicitly free the temporary LOBs any time. In OCI and Java, the returned temporary LOB needs to be freed by the user explicitly.
Without proper deallocation of the temporary LOBs returned from SQL queries, temporary tablespace gets filled up steadily and you could observe performance degradation.
The following sequence, requires a new connection when using a threaded environment, adversely affects performance, and is inaccurate:
Hence the preferred procedure is as follows:
Alternatively, you can insert >4,000 byte of data directly for the LOB columns but not the LOB attributes.
During migration from LONGs to LOBs, the redo changes for the table are logged only if the table has LOGGING on. Redo changes for the column being converted from LONG to LOB are logged only if the storage characteristics of the LOB indicate LOGGING. The default value for LOGGING|NOLOGGING for the LOB is inherited from the tablespace in which the LOB is being created.
To prevent generation of redo space during migration and migrate smoothly, use the following statements:
|
Copyright © 1996, 2002 Oracle Corporation. All Rights Reserved. |
|