我必须从具有数百万行的表中选择所有行(以预加载Coherence数据网格.)如何将此查询拆分为多个可以由多个线程并发执行的查询?
我首先考虑计算所有记录并做:
SELECT ...
WHERE ROWNUM BETWEEN (packetNo * packetSize) AND ((packetNo + 1) * packetSize)
Run Code Online (Sandbox Code Playgroud)
但那没用.现在我被卡住了.
任何帮助将非常感激.
如果您拥有Enterprise Edition许可证,则实现此目标的最简单方法是并行查询.
对于一次性或即席查询,请使用PARALLEL提示:
select /*+ parallel(your_table, 4) */ *
from your_table
/
Run Code Online (Sandbox Code Playgroud)
提示中的数字是您要执行的从属查询的数量; 在这种情况下,数据库将运行四个线程.
如果希望表上发出的每个查询都可并行化,则永久更改表定义:
alter table your_table parallel (degree 4)
/
Run Code Online (Sandbox Code Playgroud)
请注意,数据库不会始终使用并行查询; 优化器将决定它是否合适.并行查询仅适用于跨越多个分区的全表扫描或索引范围扫描.
有一些警告.并行查询要求我们有足够的内核来满足建议的线程数; 如果我们只有一个双核CPU设置,并行度为16则不会神奇地加速查询.另外,我们需要备用CPU容量; 如果服务器已经受CPU限制,那么并行执行只会让事情变得更糟.最后,I/O和存储子系统需要能够满足并发需求; SAN在这里可能非常缺乏帮助.
一如既往地在性能方面,在投入生产之前,在代表性环境中对实际数据量进行一些基准测试至关重要.
如果您没有企业版怎么办?嗯,有可能手工模仿并行执行.Tom Kyte称之为"自己动手并行".我自己使用过这种技术,效果很好.
关键是要计算出适用于表的总ROWID,并将它们分成多个作业.与此线程中提出的其他一些解决方案不同,每个作业只选择所需的行.Kyte先生在一个旧的AskTom线程中总结了这项技术,包括重要的分裂脚本:在这里找到它.
拆分表并启动线程是一项手动任务:一次性罚款,但经常做的很烦人.因此,如果您运行11g第2版,您应该知道有一个新的PL/SQL包DBMS_PARALLEL_EXECUTE可以为我们自动执行此操作.
尝试这样的事情:
select * from
( select a.*, ROWNUM rnum from
( <your_query_goes_here, with order by> ) a
where ROWNUM <= :MAX_ROW_TO_FETCH )
where rnum >= :MIN_ROW_TO_FETCH;
Run Code Online (Sandbox Code Playgroud)