【问题标题】:processing large table - how do i select the records page by page?处理大表 - 如何逐页选择记录?
【发布时间】:2023-03-20 20:12:01
【问题描述】:

我需要对表中的所有记录进行处理。该表可能非常大,所以我宁愿逐页处理记录。我需要记住已经处理过的记录,所以它们不会包含在我的第二个 SELECT 结果中。

像这样:

对于第一次运行, [从 MyTable 中选择 100 条记录]

第二轮, [从 MyTable 中选择另外 100 条记录]

等等..

我希望你能得到这张照片。我的问题是如何编写这样的选择语句?

顺便说一句,我正在使用 oracle,但如果我也可以在任何其他数据库上运行,那就太好了。 我也不想使用存储过程。

非常感谢!

【问题讨论】:

  • 您确定需要运行多个 SELECT 吗?为什么不打开游标,获取 100 条记录,处理它们,然后获取下一批。这样您就不必跟踪已处理的内容,而且查询将在开始时保持一致。
  • Paging with Oracle的可能重复

标签: sql oracle pagination


【解决方案1】:

您很可能想要利用 Oracle 的 stopkey 优化,因此当您不想要一个完整的表扫描时,您不会得到一个完整的表扫描。有几种方法可以做到这一点。第一种方式写的有点长,但是让Oracle自动算出所涉及的行数:

select *
from
(
  select rownum rn, v1.*
  from (
    select *
    from table t
    where filter_columns = 'where clause'
    order by columns_to_order_by
  ) v1
  where rownum <= 200
)
where rn >= 101;

您也可以使用 FIRST_ROWS 提示实现相同的目的:

  select /*+ FIRST_ROWS(200) */ *
  from (
    select rownum rn, t.*
    from table t
    where filter_columns = 'where clause'
    order by columns_to_order_by
  ) v1
  where rn between 101 and 200;

我更喜欢 rownum 方法,因此您不必不断更改提示中的值(这需要表示最终值,而不是实际返回到页面的行数才能准确)。您可以通过这种方式将开始值和结束值设置为绑定变量,从而避免硬解析。

更多详情可以查看this post

【讨论】:

  • OMG Ponies - 你为什么不认为第一个查询示例会起作用?它对我来说很好..
【解决方案2】:

您想出的任何将表格分成更小块的解决方案最终都将花费更多时间,而不仅仅是一次性处理所有内容。除非表是分区的,并且您一次只能处理一个分区。

如果全表扫描需要 1 分钟,则将表分解为 10 块需要 10 分钟。如果表行是按您可以使用的索引列的值进行物理排序的,则由于集群因素,这将发生一些变化。但无论如何,这比一次性处理要花更长的时间。

这当然取决于处理表中的一行需要多长时间。您可以选择通过处理数据块来减少服务器上的负载,但从性能角度来看,您无法击败全表扫描。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-15
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2020-09-28
    相关资源
    最近更新 更多