PG jdbc 驱动的cursor 的使用

商城转pg 有个索引的功能模块,

之前在oracle 端的做法是根据rownum 分页读取的,每次10w 笔记录。

转到pg后,也是采用了这个方式,似乎就不太凑效了。

如果不用order by 排序,直接使用limit  m,n  每次返回10w笔记录,似乎会有重复的数据。

第一次返回的部分记录会在第二次返回的记录集中出现。导致索引不太准确。 于是加了order by 来排序
然后用limit m,n 返回记录。结果加了这个排序后,效率低的吓人,第一个10w笔还是可以接受,之后的,就实在是无法忍受了。

于是建议开发同事用游标的方式来提取数据,这样就不用排序了,也不用多次执行sql语句了。

开发同事做了实验:
[code]
Connection conn = ((DataSource) EnvUtils.getEnv().getApplicationContext().getBean("dataSource")).getConnection();
    PreparedStatement pst = conn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
    pst.setFetchSize(10000);

java.lang.OutOfMemoryError: Java heap space

[/code]
内存溢出了,虽然我们设定了每次fetch 1w笔记录,似乎是把整个数据库里的记录全部都取出来了。

原因在哪里呢,于是去专门看了pg的jdbc 驱动的doc。

问题终于找到了。

pg 里如果要使用cursor 功能来批量处理数据,需要开启事务功能。
pg 的jdbc 的doc 里给了一个例子:
[code]

Example 5.2. Setting fetch size to turn cursors on and off.

Changing code to cursor mode is as simple as setting the fetch size of the Statement to the appropriate size. Setting the fetch size back to 0 will cause all rows to be cached (the default behaviour).

// make sure autocommit is off
conn.setAutoCommit(false);
Statement st = conn.createStatement();

// Turn use of the cursor on.
st.setFetchSize(50);
ResultSet rs = st.executeQuery("SELECT * FROM mytable");
while (rs.next()) {
   System.out.print("a row was returned.");
}
rs.close();

// Turn the cursor off.
st.setFetchSize(0);
rs = st.executeQuery("SELECT * FROM mytable");
while (rs.next()) {
   System.out.print("many rows were returned.");
}
rs.close();

// Close the statement.
st.close();

[/code]

按此方法请开发同事测试了下,果然给力。

于是动手改造了索引的这部分代码,90W 记录,完成索引大约10分钟。

而之前order by limit m,n 版本的 在测试环境跑了一个下午。 差距很大。

记于此,为后来者指路。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/133735/viewspace-733295/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/133735/viewspace-733295/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值