Oracle arraysize 和 fetch size 参数与性能优化说明(一)

2014-11-24 18:16:15 · 作者: · 浏览: 2

. 参数说明


1.1 arraysize 参数



昨天和owind 讨论问题的时候,他强调了这个参数,通过一些测试,确实与性能这块有很大影响。


Arraysize specifies how many rows SQL*Plus will fetch in a call. The number n can be between 1 and 5000.



arraysize定义了一次返回到客户端的行数,当扫描了arraysize 行后,停止扫描,返回数据,然后继续扫描。


这个过程就是统计信息中的SQL*Net roundtrips to/from client。因为arraysize 默认是15行,那么就有一个问题,因为我们一个block 中的记录数一般都会超过15,所以如果按照15行扫描一次,那么每次扫描要多扫描一个数据块,一个数据块也可能就会重复扫描多次。



重复的扫描会增加consistent gets physical reads 增加physical reads,这个很好理解,扫描的越多,物理的可能性就越大。


consistent gets,这个是从undo里读的数量,Oracle 为了保证数据的一致性,当一个查询很长,在查询之后,数据块被修改,还未提交,再次查询时候,Oracle根据Undo 来构建CR块,这个CR块,可以理解成数据块在之前某个时间的状态。 这样通过查询出来的数据就是一致的。


那么如果重复扫描的块越多,需要构建的CR块就会越多,这样读Undo 的机会就会越多,consistent gets 就会越多。



如果数据每次传到客户端有中断,那么这些数据会重新扫描,这样也就增加逻辑读,所以调整arraysize可以减少传的次数,减少逻辑读。



关于CR 参考我的Blog


CR (consistent read) blocks create 说明



所以通过上面的说明,arraysize 参数如果过低,会影响如physical readsconsistent gets 还有SQL*Net roundtrips to/from client次数。



永久保存arraysize 参数:


可以该参数保存到glogin.sql 或者login.sql 文件里,这样可以永久生效,不必每次都去set 指定。



-- 查看默认值


SYS@anqing2(rac2)> show arraysize


arraysize 15



--手工修改arraysize


SYS@anqing2(rac2)> set arraysize 100


SYS@anqing2(rac2)> show arraysize


arraysize 100



--修改glogin.sql


[oracle@rac2 admin]$ pwd


/u01/app/oracle/product/10.2.0/db_1/sqlplus/admin


[oracle@rac2 admin]$ ls


glogin.sql help iplus libisqlplus.def libsqlplus.def plustrce.sql pupbld.sql



glogin.sql里添加:


set arraysize 5000



--重新登陆,查询


SYS@anqing2(rac2)> show arraysize


arraysize 5000




1.2 fetch size 参数


arraysize fetch size 参数都是客户段的一个参数,需要在客户段来设置,arraysize 是在sqlplus 中设置的,如果我们通过程序去连数据库,那么这个参数就是Fetch size 它的作用和arraysize 一样。 Fetch size 默认是10,一般改成50ok了,太大会消耗内存。



The JDBC fetch size gives the JDBC driver a hint as to the number of rows that should be fetched from the database when more rows are needed. For large queries that return a large number of objects you can configure the row fetch size used in the query to improve performance by reducing the number database hits required to satisfy the selection criteria. Most JDBC drivers (including Oracle) default to a fetch size of 10, so if you are reading 1000 objects, increasing the fetch size to 256 can significantly reduce the time required to fetch the query''s results. The optimal fetch size is not always obvious. Usually, a fetch size of one half or one quarter of the total expected result size is optimal. Note that if you are unsure of the result set size, incorrectly setting a fetch size too large or too small can decrease performance.



In this example application, I print out the default fetch size and then increase it to 50 using the setFetchSize(int) method of a Statement object. When you execute the query, the JDBC driver retrieves the first 50 rows from the database (or all rows if less than 50 rows satisfy the selection criteria). As you iterate over the first 50 rows, each time you call rset.next(), the JDBC driver returns a row from local memory – it does not need to retrieve the row from the database. When you try to access the fifty first row (assuming there are more than 50 rows that satisfy the selection criteria), the JDBC driver again goes to the database and retrieves another 50 rows. In this way, 100 rows are returned with only two database hits.



Alternatively, you can use the method setMaxRows() to set the limit for the maximum number of rows that any ResultSet can contain. If you specify