如何将海量数据查询拆分为多个查询

Chr*_*ris 4 sql oracle select

我必须从具有数百万行的表中选择所有行(以预加载Coherence数据网格.)如何将此查询拆分为多个可以由多个线程并发执行的查询?

我首先考虑计算所有记录并做:

SELECT ... 
WHERE ROWNUM BETWEEN (packetNo * packetSize) AND ((packetNo + 1) * packetSize)
Run Code Online (Sandbox Code Playgroud)

但那没用.现在我被卡住了.

任何帮助将非常感激.

APC*_*APC 5

如果您拥有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可以为我们自动执行此操作.


Tud*_*tin 0

尝试这样的事情:

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)