Arraysize的设置以及对查询性能的影响

Arraysizesql*plus中可以设置的一个参数,这个参数设置的意思表示,sql*plus一次可以从数据库服务器端获取的记录行数。

show arraysize

arraysize 15

可以看到,在SQL*plus中,默认设置是15。有效值是1-5000。按照《Oracle9i Database Performance Tuning Guide and Reference Release 2》的说法,当这个值的设置超过100后,对性能改进基本上不会有多少帮助了。

OCIOCCI中,都可以设置这个参数,

例如,在OCCI中设置这个参数的函数是:setPrefetchRowCount()

 

做个简单的实验:

create table t as select * from all_objects;

set autotrace traceonly statistics;

 

set arraysize 2

select * from t;

 

统计信息

----------------------------------------------------------

        288  recursive calls

          0  db block gets

      25300  consistent gets

        682  physical reads

          0  redo size

    8135852  bytes sent via SQL*Net to client

     273691  bytes received via SQL*Net from client

      24848  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

      49693  rows processed

 

set arraysize 5

select * from t;

 

统计信息

----------------------------------------------------------

          0  recursive calls

          0  db block gets

      10477  consistent gets

          0  physical reads

          0  redo size

    6197846  bytes sent via SQL*Net to client

     109703  bytes received via SQL*Net from client

       9940  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

      49693  rows processed

 

set arraysize 10

select * from t;

 

统计信息

----------------------------------------------------------

          0  recursive calls

          0  db block gets

       5588  consistent gets

          0  physical reads

          0  redo size

    5551876  bytes sent via SQL*Net to client

      55044  bytes received via SQL*Net from client

       4971  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

      49693  rows processed

 

set arraysize 15

select * from t;

 

统计信息

----------------------------------------------------------

          0  recursive calls

          0  db block gets

       3952  consistent gets

          0  physical reads

          0  redo size

    5336466  bytes sent via SQL*Net to client

      36817  bytes received via SQL*Net from client

       3314  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

      49693  rows processed

 

set arraysize 100

select * from t;

 

统计信息

----------------------------------------------------------

          0  recursive calls

          0  db block gets

       1178  consistent gets

          0  physical reads

          0  redo size

    4970386  bytes sent via SQL*Net to client

       5841  bytes received via SQL*Net from client

        498  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

      49693  rows processed

 

set arraysize 500

select * from t;

 

统计信息

----------------------------------------------------------

          0  recursive calls

          0  db block gets

        786  consistent gets

          0  physical reads

          0  redo size

    4918776  bytes sent via SQL*Net to client

       1474  bytes received via SQL*Net from client

        101  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

      49693  rows processed

 

set arraysize 5000

select * from t;

 

统计信息

---------------------------------------------------------

          0  recursive calls

          0  db block gets

        697  consistent gets

          0  physical reads

          0  redo size

    4907076  bytes sent via SQL*Net to client

        484  bytes received via SQL*Net from client

         11  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

      49693  rows processed

 

set autotrace off

 

从统计信息可以看出,查询同样的结果集,当arraysize增加时,主要有几个方面的变化:

第一:consistent gets减少,表示查询需要的逻辑I/O减少;

第二:数据请求在网络间的往返次数减少,一次传送的数据多了,往返次数自然会减少;

第三:网络传输中的数据总流量减少,这主要是因为减少了网络传输中非结果集数据的开销。

 

但并不能因此就说,arraysize设置为5000是最好的,因为这样会导致客户端和服务器端使用更多的内存,并且,因为服务器必须一次性准备好5000行记录才能提供给终端,会导致终端一会在等待,一会又突然处理一大批数据,导致性能出现不稳定。

 

关于arraysize为什么会减少逻辑I/O,可以这样理解:当查询获取一个批量的记录时,其中有可能一部分记录处在同一个块中,如果缓存较少的结果集,Oracle下次不得不访问同一个块获取某些记录,如果缓存足够大,则在一次获取中,就可以把同一个块中符合条件的记录都获取到了,就避免重复访问同一个块,从而减少了逻辑I/O

 

再做一个实验,这个实验来源于《Oracle9i&10g编程艺术》,从这个实验可以看出,arraysize的增加对于查询物理存储无序的表的逻辑I/O影响不大。

先创建一个有序表:

create table colocated ( x int, y varchar2(80) );

begin

    for i in 1 .. 100000

    loop

        insert into colocated(x,y)

        values (i, rpad(dbms_random.random,75,'*') );

    end loop;

end;

/

alter table colocated

add constraint colocated_pk

primary key(x);

begin

dbms_stats.gather_table_stats( user, 'COLOCATED', cascade=>true );

end;

/

 

再创建一个无序表:

create table disorganized

as

select x,y

  from colocated

 order by y;

alter table disorganized

add constraint disorganized_pk

primary key (x);

begin

dbms_stats.gather_table_stats( user, 'DISORGANIZED', cascade=>true );

end;

/

运行下列脚本:

set arraysize 15

select * from colocated a15 where x between 20000 and 30000;

set arraysize 100

select * from colocated a100 where x between 20000 and 30000;

 

tkprof报告显示:

a15

Rows     Row Source Operation

-------  ---------------------------------------------------

  10001  TABLE ACCESS BY INDEX ROWID COLOCATED (cr=1452 pr=0 pw=0 time=100109 us)

  10001   INDEX RANGE SCAN COLOCATED_PK (cr=689 pr=0 pw=0 time=40047 us)(object id 53215)

 

a100

Rows     Row Source Operation

-------  ---------------------------------------------------

  10001  TABLE ACCESS BY INDEX ROWID COLOCATED (cr=344 pr=0 pw=0 time=90081 us)

  10001   INDEX RANGE SCAN COLOCATED_PK (cr=124 pr=0 pw=0 time=30043 us)(object id 53215)

 

Arraysize15时,对索引执行了689个逻辑I/O,对表执行了7631452-689)个逻辑I/Oarraysize100时,对索引执行了124个逻辑I/O,对表执行了220个逻辑I/O。这说明因为表有序,所以在一个块中有较多需要的记录,增加arraysize可以获得良好效果。

 

set arraysize 15

select /*+ INDEX(a15 DISORGANIZED_PK) */* from disorganized a15 where x between 20000 and 30000;

set arraysize 100

select /*+ INDEX(a100 DISORGANIZED_PK) */* from disorganized a100 where x between 20000 and 30000;

 

tkprof报告显示:

a15

Rows     Row Source Operation

-------  ---------------------------------------------------

  10001  TABLE ACCESS BY INDEX ROWID DISORGANIZED (cr=10685 pr=0 pw=0 time=180134 us)

  10001   INDEX RANGE SCAN DISORGANIZED_PK (cr=689 pr=0 pw=0 time=40336 us)(object id 53218)

 

a100

Rows     Row Source Operation

-------  ---------------------------------------------------

  10001  TABLE ACCESS BY INDEX ROWID DISORGANIZED (cr=10119 pr=0 pw=0 time=160110 us)

  10001   INDEX RANGE SCAN DISORGANIZED_PK (cr=124 pr=0 pw=0 time=30334 us)(object id 53218)

 

Arraysize15时,对索引执行了689个逻辑I/O,对表执行了999610685-689)个逻辑I/Oarraysize100时,对索引执行了124个逻辑I/O,对表执行了9995个逻辑I/O。减少的逻辑I/O基本上都来自于索引,索引本身是有序的。这说明因为表无序(表的记录信息无序),所以在一个块中有较少条需要的记录,增加arraysize效果不明显。

 

参考文献:

Oracle高效设计》

Oracle9i&10g编程艺术》

Oracle9i Database Performance Tuning Guide and Reference Release 2

Oracle C++ Call Interface Programmer's Guide 10g Release 2

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值