在数据库开发中,结果集游标(ResultSet Cursor)常用于对查询结果进行逐行处理。使用得当可以提升性能、降低内存占用;使用不当则容易造成内存溢出、连接泄漏或性能瓶颈。下面从使用场景、技巧、注意事项、常见坑几个角度总结。
避免在客户端一次性加载全部数据。
JDBC 示例(MySQL)
Statement stmt = conn.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE); // 流式读取
ResultSet rs = stmt.executeQuery("SELECT * FROM big_table");
while (rs.next()) {
// 逐行处理
}
PostgreSQL
stmt.setFetchSize(1000);
✅ 优点:内存占用低
❌ 注意:流式结果集期间通常不能执行其他 SQL
fetchSize 控制每次从数据库取多少行建议
-- 不推荐
SELECT * FROM orders
-- 推荐
SELECT id, user_id, amount FROM orders
减少 IO 和对象创建开销。
❌ 不推荐:
while (rs.next()) {
callRemoteAPI();
updateAnotherTable();
}
✅ 推荐:
while (rs.next()) {
ps.setInt(1, rs.getInt("id"));
ps.addBatch();
if (++count % 1000 == 0) {
ps.executeBatch();
}
}
ps.executeBatch();
try (Connection conn = ...;
PreparedStatement ps = ...;
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
// 处理
}
}
防止:
ResultSet.TYPE_FORWARD_ONLY
ResultSet.CONCUR_READ_ONLY
除非必须:
SCROLL_INSENSITIVE现象
max cursor open✅ 解决:try-with-resources + 连接池监控
现象
✅ 解决:
游标遍历时间长 → 锁表、日志膨胀
✅ 解决:
如 MyBatis:
<select id="list" fetchSize="1000" resultSetType="FORWARD_ONLY">
否则默认可能一次性加载。
游标的核心技巧是:流式读取、批量处理、尽早释放、避免重操作。
如果你用的是 具体数据库(Oracle / MySQL / PG)或语言(Java / Python),我可以给你更针对性的示例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。