Professional Documents
Culture Documents
Oracle 12c Datatypes
Oracle 12c Datatypes
12c has introduced character strings that can can go above 4000 bytes. In the
previous versions, in PL/SQL only we were allowed to have VARCHAR2 up to 32k. In
SQL the VARCHAR2 datatype was limited to 4000 and CHAR was limited to 2000. That
became a bit small especially when lot of applications needed to store unicode
characters.
From 12c we can have SQL datatypes having up to 32k bytes for VARCHAR2, CHAR and
RAW. It�s not allowed by default. We need to set max_string_size=extended and
recompile views with utl32k. Nice improvement. But is it a good idea to use that
new feature when we already have CLOB for large character strings ? The New
Features documentation is clear about that: extended datatypes have been introduced
to be compatible with other databases � not to replace existing features.
I will not go into the details how they are stored. Information about that is
available elsewhere. See for example @ludodba recent blog post Where are Extended
Data Types stored?. Extended datatypes are stored as chained rows if you just
extend an existing table, or as a LOB if you defined them on a new table. Chained
rows is clearly not a good option, so, given that you (re)create the tables, their
storage is similar to CLOB.
But there is something that I don�t like with LOBS: they are fetched row by row.
When you select a row you get only the handle. And you get the CLOB later when you
access to it through the handle. Did you ever try to datapump a table with LOBs
through network_link? Huge amount of roundtrips and very bad performance. It�s one
rare case where doing expdp/impdp with a dumpfile is better. For very large
objects, you will do several roundtrips anyway, so this is not an issue. But with
character strings that are just a few kilobytes having them as LOB introduces an
ineffective overhead.
Let�s compare the fetch behaviour with those new extended datatypes. For my demo,
I�ll use a table with a clob column �C� and an extended varchar2 column �E�, and
insert same data into both columns.
10 rows selected.
Statistics
----------------------------------------------------------
2 recursive calls
0 db block gets
27 consistent gets
20 physical reads
0 redo size
93936 bytes sent via SQL*Net to client
2722 bytes received via SQL*Net from client
22 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10 rows processed
For only 10 rows I�ve made 22 roundtrips. This is the problem with LOBs. Too many
roundtrips. Well there is another problem that I�ll not show here, which is the
fact that you can fetch the lob a long time after, even when the cursor is closed.
It does consistent read so you have to set your undo_retention accordingly.
Now here is the same data from the extended varchar2 column:
10 rows selected.
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
56 consistent gets
0 physical reads
0 redo size
90501 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10 rows processed
Here I got the same volume (10 times 9000 characters) but this time I did only 2
roundtrips.
Let�s go further and trace with sql_trace. LOB calls are instrumented since 11g so
we can see them from the trace file:
And the sql_trace with the same data from the extended datatype.
So there is is one big advantage over CLOB: the column values are returned without
additional roundtrips.
That would mean that if you have character strings that may be between 4k and 32k
then extended datatypes can be a good option. It�s a new feature however, and
designed for another goal (easy migration from other databases). So it�s something
to test carefully and the tests must integrate all you infrastructure components
(backups, exports, replication, etc).