2011-04-09 141 views
2

如果ResultSet是巨大的,这将是节省内存使用光标?使用游标时interate在结果集,将所有的结果集加载到内存中

+0

你试图解决什么问题?也许另一种使用游标的解决方案将会更好。 – jfs 2011-04-09 04:19:52

+0

这包括你的问题的甲骨文方面:区别FETCH/FOR循环在PL/SQL游标(http://stackoverflow.com/questions/3885469/difference-between-fetch-for-to-loop-一个光标式-PL-SQL) – 2011-04-09 04:23:10

回答

3

从技术上讲,光标总是参与,当你发出数据库查询。您可能正在考虑隐式和显式游标之间的区别?

就内存使用而言,它不是发出查询的方法,而是您如何获取结果 - 您可以选择以批量方式获取结果(使用更多内存,但性能更好,效率更高)或单独获取每行(使用较少的内存,但性能更差且效率更低)。

然而,权衡是不是这么简单。如果您拥有大量并发连接(同时运行所有查询),那么效率可能比内存使用更重要 - 查询完成后越早,数据库就可以自由地为其他请求提供服务。

如果我试图以优化性能和内存使用我的PL/SQL,我喜欢使用BULK收集,以限制环内,例如:

DECLARE 
    BATCHSIZE CONSTANT INTEGER := 1000; 
    CURSOR mycursor IS SELECT ...; 
    TYPE mytabletype IS TABLE OF mycursor%ROWTYPE INDEX BY PLS_INTEGER; 
    myarray mytabletype; 
BEGIN 
    OPEN mycursor; 
    LOOP 
    FETCH mycursor INTO myarray LIMIT BATCHSIZE; 
    EXIT WHEN myarray.COUNT = 0; 
    FOR i IN 1..myarray.COUNT LOOP 
     -- do the processing on myarray(i) 
    END LOOP; 
    END LOOP; 
    CLOSE mycursor; 
END; 

上面的代码变得非常简单调整批量大小以最大化吞吐量,而不会在每个会话中使用太多内存。

3

在一般情况下,你应该尝试使用“设置”是一组基于一个查询,而不是使用游标并遍历数据记录操作SQL statmenets。大多数dbas认为游标是邪恶的,因为它们占用太多的内存,涉及阻止执行其他任务的锁,并且比没有深思熟虑的sql语句更加低效(有时几个数量级)。