Oracle—与Varchar列相比,包含少于4K行的CLOB列的性能是否受到影响?
如果您需要存储大部分(如果不是全部)小于4K字节的字符串,那么在VARCHAR2数据类型上使用CLOB数据类型是否有任何负面影响 从 CLOB可以存储在单独的LOB段中,指向LOB段的指针与表的其余数据一起存储在数据块中。如果使用CREATETABLE语句,则可以使用LOB storage子句控制LOB段的存储位置。默认情况下,小于约4000字节的LOB将以与VARCHAR2相同的方式存储,即与其余数据保持一致 发件人: 当您使用CLOB列创建表时,有一个名为“在行中启用存储”的选项用于CLOB。这决定了CLOB是存储在与表相同的段中,从而与表行的其余部分一起存储,还是单独存储在单独的段中。在第二种情况下,表行将包含一个指向CLOB数据位置的指针。通常,将CLOB与表行一起存储更为有效,但如果CLOB长度超过约4000个字符,则不能再将其存储在行中,而无论是否启用了行中的存储,它都将存储在CLOB段中Oracle—与Varchar列相比,包含少于4K行的CLOB列的性能是否受到影响?,oracle,varchar,clob,varchar2,Oracle,Varchar,Clob,Varchar2,如果您需要存储大部分(如果不是全部)小于4K字节的字符串,那么在VARCHAR2数据类型上使用CLOB数据类型是否有任何负面影响 从 CLOB可以存储在单独的LOB段中,指向LOB段的指针与表的其余数据一起存储在数据块中。如果使用CREATETABLE语句,则可以使用LOB storage子句控制LOB段的存储位置。默认情况下,小于约4000字节的LOB将以与VARCHAR2相同的方式存储,即与其余数据保持一致 发件人: 当您使用CLOB列创建表时,有一个名为“在行中启用存储”的选项用于CLOB
从这些语句中,我觉得将列声明为CLOB并没有任何惩罚,即使所有行包含的行都少于4K行。这是否准确?使用LOB数据类型时会产生重大影响,例如:
- 根据您读取数据的方式,即使数据存储在行中,每行LOB访问也可能意味着额外的网络往返
- 优化器可以在VARCHAR列、直方图、更精确的长度、绑定窥视等方面使用更多的统计信息
- 某些执行计划优化不适用于LOB列,例如,分解子查询的物化
- 许多SQL函数不能与LOB一起使用
HUSQVIK@hq_pdb_tcp> CREATE TABLE t_varchar AS SELECT CAST('data' AS VARCHAR2(4)) c1 FROM DUAL CONNECT BY LEVEL <= 10;
Table created.
HUSQVIK@hq_pdb_tcp> CREATE TABLE t_clob AS SELECT to_clob('data') c1 FROM DUAL CONNECT BY LEVEL <= 10;
Table created.
HUSQVIK@hq_pdb_tcp> SET AUTOT TRACE
HUSQVIK@hq_pdb_tcp> SELECT * FROM t_varchar;
10 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 4100862799
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10 | 50 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| T_VARCHAR | 10 | 50 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
5 recursive calls
0 db block gets
5 consistent gets
5 physical reads
0 redo size
682 bytes sent via SQL*Net to client
551 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10 rows processed
HUSQVIK@hq_pdb_tcp> SELECT * FROM t_clob;
10 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3459655851
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10 | 410 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| T_CLOB | 10 | 410 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------
Statistics
----------------------------------------------------------
2 recursive calls
0 db block gets
23 consistent gets
5 physical reads
0 redo size
3433 bytes sent via SQL*Net to client
3231 bytes received via SQL*Net from client
12 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10 rows processed
HUSQVIK@hq_pdb_tcp>创建表t_varchar作为选择转换(“数据”作为VARCHAR2(4))c1从双连接逐层创建表t_clob作为选择从双连接逐层设置自动跟踪创建表t_clob作为选择到clob(“数据”)c1
HUSQVIK@hq_pdb_tcp>从t_varchar中选择*;
选择10行。
执行计划
----------------------------------------------------------
计划哈希值:4100862799
-------------------------------------------------------------------------------
|Id |操作|名称|行|字节|成本(%CPU)|时间|
-------------------------------------------------------------------------------
|0 |选择语句| | 10 | 50 | 3(0)| 00:00:01|
|1 |表访问完整| T|u VARCHAR | 10 | 50 | 3(0)| 00:00:01|
-------------------------------------------------------------------------------
统计
----------------------------------------------------------
5个递归调用
0 db块获取
5个一致的
5物理阅读
0重做大小
682字节通过SQL*Net发送到客户端
通过SQL*Net从客户端接收551字节
与客户端之间的2次SQL*Net往返
0排序(内存)
0排序(磁盘)
已处理10行
HUSQVIK@hq_pdb_tcp>从t_clob中选择*;
选择10行。
执行计划
----------------------------------------------------------
计划哈希值:3459655851
----------------------------------------------------------------------------
|Id |操作|名称|行|字节|成本(%CPU)|时间|
----------------------------------------------------------------------------
|0 | SELECT语句| 10 | 410 | 3(0)| 00:00:01|
|1 |表访问完整| T| u CLOB | 10 | 410 | 3(0)| 00:00:01|
----------------------------------------------------------------------------
统计
----------------------------------------------------------
2个递归调用
0 db块获取
23一致性得到
5物理阅读
0重做大小
3433字节通过SQL*Net发送到客户端
通过SQL*Net从客户端接收3231字节
12往返于客户端的SQL*Net往返
0排序(内存)
0排序(磁盘)
已处理10行
还请注意,一致性GET的数量增加了,因为Oracle在每次往返时都会反复处理包含LOB数据的同一块。为什么即使数据存储在第行中也会有额外的往返?@MatthewMoisen据我所知,行为取决于您使用的驱动程序或其设置,我在SQL*Plus中添加了一个简单的示例,在这个示例中,我无法在同一个往返中获取LOB数据。