Oracle 10g small Blob or Clob not being stored inline?

前端 未结 5 980
一个人的身影
一个人的身影 2021-02-14 00:42

According to the documents I\'ve read, the default storage for a CLOB or BLOB is inline, which means that if it is less than approx 4k in size then it will be held in the table.

5条回答
  •  别那么骄傲
    2021-02-14 01:26

    If you're "hoping to achieve similar response times to reading the varchar2 column z", then you'll be disappointed in most cases. If you're using a CLOB I suppose you need to store more than 4,000 bytes, right? Then if you need to read more bytes that's going to take longer.

    BUT if you have a case where yes, you use a CLOB, but you're interested (in some instances) only in the first 4,000 bytes of the column (or less), then you have a chance of getting similar performance. It looks like Oracle can optimize the retrieval if you use something like DBMS_LOB.SUBSTR and ENABLE STORAGE IN ROW CACHE clause with your table. Example:

    CREATE TABLE clobtest (x INT PRIMARY KEY, y CLOB)
    LOB (y) STORE AS (ENABLE STORAGE IN ROW CACHE);
    
    INSERT INTO clobtest VALUES (0, RPAD('a', 4000, 'a'));
    UPDATE clobtest SET y = y || y || y;
    INSERT INTO clobtest SELECT rownum, y FROM all_objects, clobtest WHERE rownum < 1000;
    
    CREATE TABLE clobtest2 (x INT PRIMARY KEY, z VARCHAR2(4000));
    
    INSERT INTO clobtest2 VALUES (0, RPAD('a', 4000, 'a'));
    INSERT INTO clobtest2 SELECT rownum, z FROM all_objects, clobtest2 WHERE rownum < 1000;
    
    COMMIT;
    

    In my tests on 10.2.0.4 and 8K block, these two queries give very similar performance:

    SELECT x, DBMS_LOB.SUBSTR(y, 4000) FROM clobtest;
    SELECT x, z FROM clobtest2;
    

    Sample from SQL*Plus (I ran the queries multiple times to remove physical IO's):

    SQL> SET AUTOTRACE TRACEONLY STATISTICS
    SQL> SET TIMING ON
    SQL>
    SQL> SELECT x, y FROM clobtest;
    
    1000 rows selected.
    
    Elapsed: 00:00:02.96
    
    Statistics
    ------------------------------------------------------
              0  recursive calls
              0  db block gets
           3008  consistent gets
              0  physical reads
              0  redo size
         559241  bytes sent via SQL*Net to client
         180350  bytes received via SQL*Net from client
           2002  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
           1000  rows processed
    
    SQL> SELECT x, DBMS_LOB.SUBSTR(y, 4000) FROM clobtest;
    
    1000 rows selected.
    
    Elapsed: 00:00:00.32
    
    Statistics
    ------------------------------------------------------
              0  recursive calls
              0  db block gets
           2082  consistent gets
              0  physical reads
              0  redo size
          18993  bytes sent via SQL*Net to client
           1076  bytes received via SQL*Net from client
             68  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
           1000  rows processed
    
    SQL> SELECT x, z FROM clobtest2;
    
    1000 rows selected.
    
    Elapsed: 00:00:00.18
    
    Statistics
    ------------------------------------------------------
              0  recursive calls
              0  db block gets
           1005  consistent gets
              0  physical reads
              0  redo size
          18971  bytes sent via SQL*Net to client
           1076  bytes received via SQL*Net from client
             68  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
           1000  rows processed
    

    As you can see, consistent gets are quite higher, but SQL*Net roundtrips and bytes are nearly identical in the last two queries, and that apparently makes a big difference in execution time!

    One warning though: the difference in consistent gets might become a more likely performance issue if you have large result sets, as you won't be able to keep everything in buffer cache and you'll end up with very expensive physical reads...

    Good luck!

    Cheers

提交回复
热议问题