如果结果集很大,使用游标会有内存效率吗?
答案 0 :(得分:3)
通常,您应该尝试使用基于查询操作基于一组记录的“set”SQL语句,而不是使用游标并循环遍历数据。大多数DBA认为游标是邪恶的,因为它们占用了太多的内存,涉及阻止其他任务执行的锁,并且与经过深思熟虑的SQL语句相比效率也低得多(有时几个数量级)。
答案 1 :(得分:3)
从技术上讲,当您发出数据库查询时,游标始终。您可能正在考虑隐式和显式游标之间的区别吗?
就内存使用而言,重要的不是发出查询的方法,而是获取结果的方法 - 您可以选择批量获取结果(使用更多内存,但执行效果更好,效率更高)或单独获取每一行(使用较少的内存,但性能更差,效率更低)。
然而,权衡并非如此简单。如果你有大量的并发连接,所有同时运行的查询,效率可能比内存使用更重要 - 查询越早完成,数据库就越早可以提供其他请求。
如果我正在尝试优化我的PL / SQL以提高性能和内存使用率,我喜欢使用BULK COLLECT,在循环中使用LIMIT,例如:
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;
上面的代码可以很容易地调整批量大小以最大化吞吐量,而不会在每个会话中使用太多内存。