SQL优化-同SQL不同执行计划-(CLOB详细分析1)

原文链接:  http://blog.csdn.net/ehuman/article/details/2449958

有个问题一直没有详细讨论,为什么在数据里检索147条记录速度明显慢于1万条记录。
SQL回顾一下,
SQL 1 】:
select art.article_id, art.article_title, aps.adminaccount
 from tbnc_a art, tbnc_p aps
 where art.column_id = aps.scopestr
   and aps.funcnodepath = 'A001B002C002D002E003'
   and aps.adminaccount = ' lgm ';
 
SQL 2 】:
select art.article_id, art.article_title, aps.adminaccount
 from tbnc_a art, tbnc_p aps
 where art.column_id = aps.scopestr
   and aps.funcnodepath = 'A001B002C002D002E003'
   and aps.adminaccount = ' admin_two ';
 
两个 SQL 除了【 aps.adminaccount 】等于的值不同,其他完全一致,
             执行时间 ( 平均 )       执行结果数
SQL 1         3.906  S                                    148
SQL 2         0.531  S                                    11421 
 
今天查查了我原来的好多资料,仔细的研究了Lob类型的存储方式,终于解开了这个迷。
为了方便呈现结构,我先解释一下Lob的存储方式。
在Oracle里有很多CLob字段属性,都默认的,不需要人工介入,这其中就包括了影响我们这次结果的【in row】和【nocache】属性。
平常我们都是这样建立一个带Clob类型的表,代码如下:
Create table lob_table
(
       Id  int primary key,
       Txt        clob
);
在创建CLob类型的时候并没有指定【in row】和【nocache】属性,这些属性都是使用默认,lob_Table建立后,我们怎么知道Clob的默认属性设置呢?
我们可以通过以下SQL语句获取完整的lob_table定义:
Select dbms_metadata.get_ddl(‘TABLE’,’LOB_TABLE’);           注:所有数据必须大些(TABLE和表名)!
你仔细阅读可能发现,DDL语句中,包含了很多我们没有设置的属性。其中一段代码如下:
…………
Lob(“TXT”) store as (
       TABLESPACE “USERS” ENABLE STORAGE IN ROW CHUNK 8192 PCTVERSION 10
    NOCACHE
       STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENT………)
………..
Lob包含了:
【表空间】
【ENABLE STORAGE IN ROW】默认属性
【CHUNK】8192
【NOCACHE】非缓冲
等等
 
可以看出,TXT字段并不是简单的存储,而是拥有自己的表空间。CLOB列总四会带来一种多段对象,它会使用多个物理段。创建CLOB段一般来说,存储在行中的只是一个指针,或Lob定位器,我们的应用所获取的就是这个CLOB定位器。当我们请求得到CLOB的时,将对更具这个具体定位到一个特定的物理区域。而且CLOB默认是不缓存的,所以每个CLOB的读还是写,都会带来一个物理I/O。默认缓存设置属性为【NOCACHE】,也就是不缓存。
 
前面还说过一个属性叫【ENABLE STORAGE IN ROW】,这是Oracle对CLOB字段小于4000字节的设置,也是Oracle提高Lob读取速度的重要手段。你可以这样理解,如果CLOB存储的数据大于4000字节,那么他就会使用【行外存储模式】,记录行内只存储【定位器】,如果数据小于4000字节,如果设置了【ENABLE STORAGE IN ROW】,那么就会选择【行内存储模式】,把CLOB字段当作Varchar2来处理,这就和我们平常定义Varchar2一样使用,而不需要而外的空间。
 
说到这里大家也许就能明白了,为什么在
aps.adminaccount = ' admin_two '】的时候,数据检索出1万条记录,所用的时间比
aps.adminaccount = ' lgm '】时间少。
可以大胆的推断,
【Admin_two】检索的记录中,CLOB大部分都是是小4000字节的数据,不需要额外的I/O。
而 【lgm】检索的出来的记录,至少普遍存在,或是存在个别超大的CLOB字段,导致需要额外的I/O所致。
 
综合上述,结果很清晰了,不知道大家明白了,我还会继续整理,希望能拿出真是可靠的数据作为例证。
加油。。。。

你可能感兴趣的:(oracle,查询,clob,优化器)