您的位置:首页 > 数据库

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

2014-10-22 14:28 363 查看
原文链接: 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 优化器