IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

化整为零访问大表的三种方式

Alibaba DBA Team 2010-01-14 09:29:11 累计浏览 1,934 次
本机暂存

    业务场景:

    表xngul 大小大于 100G。

    上面有(id)是number型自增字段,且是pk。

    现在有需求要对这个表进行全表扫描,如果直接 select * from xngul, 则至少要半个小时,

    而且一次性返回数据过多,应用程序无法处理。

    所以想了办法化整为零,将这个表分段,分段读取。

    有以下三种方式。

    *******I.两个步骤,一个取分段的头尾,一个按头尾取分段内数据。*********

    -取分段的头尾

    select min(id) as min_id,

     max(id) as max_id

    from

     (select /*+index (xngul xngul_pk)*/id

     from xngul

     where id > :last_max_id

     order by id)

    where rownum <= :page_size;

    -按头尾取中间的数据

    select *

    from xngul

    where id between :min_id and :max_id;

    **********************************************************************

    ――――――――――――――――――――――――――――-

    **************II.一个步骤,完成分段和取数据。*************************

    -在一个sql中完成分段和取数据

    select /*+ordered use_nl(b)*/

     b.*

    from

     (select id

     from

     (select /*+index (xngul xngul_pk)*/id

     from xngul

     where id > :last_max_id

     order by id) a

     where rownum <= :page_size) a, xngul b

    where a.id=b.id;

    **********************************************************************

    ――――――――――――――――――――――――――――-

    ********III.借助一个表,实现多个进程并发处理。************************

    -将分段数据记录到表中,并给每个段赋予一个 batch_id 和 batch_status

    insert into batch

    (batch_id, batch_status, ceiling_id, floor_id)

    select

     seq_batch.nextval as batch_id,

     ’not dealed’ as batch_status,

     max(id) as ceiling_id,

     min(id) as floor_id

    from

     (select /*+index (xngul xngul_pk)*/id

     from xngul

     where id > :last_max_id

     order by id)

    where rownum <= :page_size;

    -多进程并发取未处理的batch_id

    select batch_id, ceiling_id, floor_id

    from batch for update nowait

    where batch_status=’not dealed’

    and rownum<=1;

    -取该batch_id的明细数据

    select *

    from xngul

    where id between :min_id and :max_id;

    -处理完毕后,更新该batch_status

    update batch

    set batch_status=’has dealed’

    where batch_id=:batch_id;

    **********************************************************************

    该方式还可以再扩展:

    1,如果对数据实时性要求不高,可以在standby上按rowid来分段读取,效率会更高。

    2,如果要做表连接,则可以对其中的大表做这个分段,分段的结果再来跟其他小表做连接,同样可以达到化整为零的目的。

同分类推荐文章

  1. 使用deepseek进行Oracle恢复,引起重大故障 (2026-06-22 10:56:00)
  2. 接手一个只差临门一脚的数据库恢复 (2026-06-18 00:13:09)
  3. 我做了一个 AI 版的 StarRocks 升级风险扫描工具,直接帮我定位到一个风险 (2026-06-15 01:00:00)

查看更多 数据库 文章 →

建议继续学习

  1. WordPress评论翻页造成404页面的解决方案 (累计阅读 9,539)
  2. 深入理解Linux内存管理机制(一) (累计阅读 5,032)
  3. 独创比百度、Google分页还强的分页类 (累计阅读 4,837)
  4. 高效的MySQL分页 (累计阅读 3,877)
  5. MySQL DBA面试全揭秘 (累计阅读 3,701)
  6. 用Twitter的cursor方式进行Web数据分页 (累计阅读 3,239)
  7. Oracle数据库性能模型 (累计阅读 3,114)
  8. MySQL processlist中哪些状态要引起关注 (累计阅读 2,051)