2

朋友们,

我有订单表,每个表中至少有 1 亿条记录。我们有一个正在运行的作业,它调用一个存储过程,该过程每天删除至少 50K (MIN) 和 200K (MAX) 记录。

我目前正在使用 SQL BULK COLLECT 从表中删除记录。目前删除 50K 需要 4 个多小时,这非常慢。

在谷歌搜索后,找出CTAS方法,即创建表并保留我们想要的记录并删除现有的记录并重命名临时表。我不能这样做,因为这个选项不被接受,因为表格更重要。

您能否提出一些解决方案来提高其性能?

提前致谢!!

4

2 回答 2

1

假设您有足够的物理磁盘空间来复制数据,您可以使用以下方法(我假设您的表称为 ORDERS):

  • 创建您的订单表的副本 ORDER_BCREATE TABLE orders_b AS SELECT * FROM orders
  • 将原始表重命名为 ORDERS_A:ALTER TABLE orders RENAME TO orders_a
  • 创建一个名为 ORDERS 的同义词,指向 ORDERS_A:CREATE SYNONYM orders FOR order_a

到现在为止还挺好。您的客户端代码现在使用同义词 ORDERS 而不是物理表。现在是有趣的部分(每日刷新程序):

  • 截断 ORDERS_B
  • 填写 ORDERS_B INSERT /*+APPEND+*/(您可能还想尝试 PARALLEL 提示)
  • 将同义词 ORDERS 切换为指向 ORDERS_B
  • 第二天:用 ORDERS_A 代替 ORDERS_B 重复
  • 无限重复

或者,您可以删除表并重新创建它,而不是使用 TRUNCATE/INSERT。这需要更多的工作,因为您还必须重新创建索引和授权。

这种技术称为同义词切换 - 您可能想阅读Tyler Muth 关于同义词切换的文章以获得更完整的解释。

于 2014-05-15T06:37:30.107 回答
0

删除记录的条件是什么?

也许您可以在此表上创建基于函数的索引。然后,您可以使用一个简单的删除语句删除记录。或者考虑一下表分区。如果您的分区键很智能并且涵盖了删除条件,您可以在几秒钟内删除或清除旧分区。

顺便说一句,DBMS_REDEFINITION即使不中断服务,您也可以使用包将“正常”表更改为分区表。

于 2014-05-15T09:23:29.483 回答