Oracle—与Varchar列相比,包含少于4K行的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

如果您需要存储大部分(如果不是全部)小于4K字节的字符串,那么在VARCHAR2数据类型上使用CLOB数据类型是否有任何负面影响

CLOB可以存储在单独的LOB段中,指向LOB段的指针与表的其余数据一起存储在数据块中。如果使用CREATETABLE语句,则可以使用LOB storage子句控制LOB段的存储位置。默认情况下,小于约4000字节的LOB将以与VARCHAR2相同的方式存储,即与其余数据保持一致

发件人:

当您使用CLOB列创建表时,有一个名为“在行中启用存储”的选项用于CLOB。这决定了CLOB是存储在与表相同的段中,从而与表行的其余部分一起存储,还是单独存储在单独的段中。在第二种情况下,表行将包含一个指向CLOB数据位置的指针。通常,将CLOB与表行一起存储更为有效,但如果CLOB长度超过约4000个字符,则不能再将其存储在行中,而无论是否启用了行中的存储,它都将存储在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数据。