文档章节

Postgres查询结果集的获取方法及其优缺点

YuanyuanL
 YuanyuanL
发布于 2015/03/18 17:11
字数 1360
阅读 191
收藏 0

PG jdbc的查询结果集获取方式

1 简单全部结果集查询

    默认情况下,pgjdbc是一次获取全部查询结果的,并且结果集的类型和并发性分别为ResultSet.TYPE_FORWARD_ONLY和ResultSet.CONCUR_READ_ONLY。也就是pgjdbc默认会一次获取全部查询结果,只能从前往后取,是只读的。

     stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
     rs = stmt.executeQuery(sql);
     while(rs.next())
     {
             ...
     }

  通过修改结果集的类型和并发性,还分别可以获得(不)可滑动的,对变化(不)敏感的,(不)可更新的结果集。

 ResultSet类型API: http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#TYPE_SCROLL_SENSITIVE

    ResultSet.TYPE_FORWARD_ONLY                        ResultSet.CONCUR_READ_ONLY

    ResultSet.TYPE_SCROLL_INSENSITIVE                  ResultSet.CONCUR_UPDATABLE

    ResultSet.TYPE_SCROLL_SENSITIVE

    该方法一次获取全部结果:对于数据量小的查询来说,速度更快,结果集有多种灵活的获取方式;但对于数据量很大的查询,容易造成很大的内存消耗,甚至内存溢出。


2  基于游标的批量结果集查询

   通过设置setFetchSize(int size)获取基于游标cursor的结果集,size>0表示开启游标,一次只获取size行结果集,该size取完后在获取下一size的结果集;size=0表示关闭游标,结果集一次取出全部行

 基于游标的结果集的使用是有条件的,如果不满足条件setFechSize(int size)将不起作用,pgjdbc还是会一次获取全部结果集。基于游标的结果集使用条件如下:

 1.连到数据库服务的连接必须是基于V3协议的,V3协议是7.4及更新版本PG才能支持的,并且是他们的默认协议;

 2.Connection必须是非自动提交模式.后端会在事务的结束的时候关闭游标,所以,在自动提交模式里,还没从游标里获取任何东西的时候,后端就已经把游标关闭了。

 3.Statement必须以ResultSet.TYPE_FORWARD_ONLY的类型来创建,该结果集类型是默认的,所以可以直接使用stmt = conn.createStatement()来创建(或者stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY)).因此基于游标的结果集是只能向前获取,不能向后或者跳跃获取的。

 4. 查询sql语句必须是一个单一的语句,不能是由分好分隔的多个语句。

// 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();

  该方法分批获取结果集,一次仅获取一个批量的数据,只有一个小批量的行集缓存在连接的客户端,当该批量用尽后才会通过重定位游标来获取下一批量的行集:对于数据量小的查询,由于分批获取,会导致查询速度降低,结果集取得的灵活性也不可用了;但是对于数据量大的查询,分批获取,首次获得结果的速度加快,降低了内存的消耗的阀值,可以避免内存溢出的问题。


桥哥的博客:http://blog.chinaunix.net/uid-20726500-id-4844406.html

JAVA API:  http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#TYPE_SCROLL_SENSITIVE

PG JDBC Last Doc: https://jdbc.postgresql.org/documentation/head/query.html#query-with-cursor

原文如下:

Chapter 5. Issuing a Query and Processing the Result

Table of Contents

    Getting results based on a cursor

    Using the Statement or PreparedStatement Interface

    Using the ResultSet Interface

    Performing Updates

    Creating and Modifying Database Objects

Any time you want to issue SQL statements to the database, you require a Statement or PreparedStatement instance. Once you have a Statement or PreparedStatement, you can use issue a query. This will return a ResultSet instance, which contains the entire result (see the section called “Getting results based on a cursor” here for how to alter this behaviour). Example 5.1, “Processing a Simple Query in JDBC” illustrates this process.

Example 5.1. Processing a Simple Query in JDBC

This example will issue a simple query and print out the first column of each row using a Statement.

Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE columnfoo = 500");
while (rs.next())
{
   System.out.print("Column 1 returned ");
   System.out.println(rs.getString(1));
} rs.close();
st.close();

This example issues the same query as before but uses a PreparedStatement and a bind value in the query.

int foovalue = 500;
PreparedStatement st = conn.prepareStatement("SELECT * FROM mytable WHERE columnfoo = ?");
st.setInt(1, foovalue);
ResultSet rs = st.executeQuery();
while (rs.next())
{
   System.out.print("Column 1 returned ");
   System.out.println(rs.getString(1));
}
rs.close();
st.close();

Getting results based on a cursor

By default the driver collects all the results for the query at once. This can be inconvenient for large data sets so the JDBC driver provides a means of basing a ResultSet on a database cursor and only fetching a small number of rows.

A small number of rows are cached on the client side of the connection and when exhausted the next block of rows is retrieved by repositioning the cursor.

Note

Cursor based ResultSets cannot be used in all situations. There a number of restrictions which will make the driver silently fall back to fetching the whole ResultSet at once.

The connection to the server must be using the V3 protocol. This is the default for (and is only supported by) server versions 7.4 and later.

The Connection must not be in autocommit mode. The backend closes cursors at the end of transactions, so in autocommit mode the backend will have closed the cursor before anything can be fetched from it. *The Statement must be created with a ResultSet type of ResultSet.TYPE_FORWARD_ONLY. This is the default, so no code will need to be rewritten to take advantage of this, but it also means that you cannot scroll backwards or otherwise jump around in the ResultSet.

The query given must be a single statement, not multiple statements strung together with semicolons.

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();


© 著作权归作者所有

YuanyuanL

YuanyuanL

粉丝 154
博文 334
码字总数 194722
作品 0
济南
高级程序员
私信 提问
加载中

评论(0)

PostgreSQL 实践 - 实时广告位推荐 2 (任意字段组合、任意维度组合搜索、输出TOP-K)

标签 PostgreSQL , gin , 倒排 , rum , ginfuzzysearch_limit , 随机采样 , 分区索引 , 分段索引 , score分段 背景 任意字段组合查询的几种优化方法: 1、列存 2、RUM 3、GIN 4、多个INDEX的...

德哥
2018/05/06
0
0
postgresql数据库常用命令(资源)

进入数据库 #su - postgres #切换用户,执行后提示符会变为 '-bash-4.2$' #psql -U postgres #登录数据库,执行后提示符变为 'postgres=#' #ALTER USER postgres WITH PASSWORD 'postgres' #......

寰宇01
2019/09/03
79
0
PostgreSQL体系结构小结

 参考:http://book.51cto.com/art/201201/313175.htm 体系架构 PostgreSQL数据库由连接管理系统(系统控制器)、编译执行系统、存储管理系统、事务系统、系统表五大部分组成,其组成结构和...

YuanyuanL
2015/08/26
2.6K
0
任意编程语言访问PostgreSQL:PHP接口

【IT168 技术】在数据库与网页集成方面,PHP是一项广泛使用的技术。PHP语言向程序员提供了一种简单的方式来与数据交互。   相关文章:   任意语言访问PostgreSQL:C语言接口   任意编程...

作者:Taskiller 译
2012/03/13
0
0
PostgreSQL函数如何返回数据集

以下主要介绍PostgreSQL函数/存储过程返回数据集,或者也叫结果集的示例。 背景: PostgreSQL里面没有存储过程,只有函数,其他数据库里的这两个对象在PG里都叫函数。 函数由函数头,体和语言...

kenyon_君羊
2013/02/07
1.9W
14

没有更多内容

加载失败,请刷新页面

加载更多

微服务-(Hystrix应用及原理)

Hystrix 的应用及原理 一.通过配置文件的方式使用hystrix 二.演示断路效果 三.通过图片查询断路流程 四.注解的方式演示hystrix this.metrics = initMetrics(metrics, this.commandGroup, th...

这很耳东先生
6分钟前
38
0
如何将旧Mac的数据迁移到新的MacBook Pro?

最新版的MacBook Pro已经上市,具有超凡魅力的Touch Bar开创了一个新时代。苗条的设计和华丽的显示效果也起到了推动运动的作用……!将数据从旧Mac传输到新Mac不再是一件漫长的事。您只需几个...

mac小叮当
8分钟前
22
0
推荐一款好用的第三方的windows远程管理工具

iis7远程桌面连接工具,又叫做iis7远程桌面管理软件,是一款绿色小巧,功能实用的远程桌面管理工具,其界面简洁,操作便捷,能够同时远程操作多台服务器,并且多台服务器间可以自由切换,适用...

汉美丽
12分钟前
31
0
使用.text()仅检索未嵌套在子标记中的文本

如果我有这样的html: <li id="listItem"> This is some text <span id="firstSpan">First span text</span> <span id="secondSpan">Second span text</span></li> 我正在尝试......

javail
18分钟前
27
0
MySQL调优系列——如何提高MySQL的查询效率

1、对查询进行优化,避免全表扫描,首先应考虑在where及order by涉及的列上建立索引。 2、避免在where子句对字段进行null值判断,否则会导致引擎放弃使用索引而进行全表扫描。 3、应尽量避免...

须臾之余
19分钟前
20
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部