代码之家  ›  专栏  ›  技术社区  ›  Robert Brown

避免填写事务日志的Oracle SQL技术

  •  2
  • Robert Brown  · 技术社区  · 16 年前

    新的Oracle编程(从Sybase和MS SQL Server)。“Oracle方法”是什么,以避免用大更新填充Trans日志?

    在我的具体案例中,我正在更新可能非常多的行。我的方法是:

    UPDATE my_table
    SET a_col = null
    WHERE my_table_id IN 
    (SELECT my_table_id FROM my_table WHERE some_col < some_val and rownum < 1000)
    

    …在循环中执行此操作,直到更新的行计数为零,

    这是最好的方法吗?

    谢谢,

    3 回复  |  直到 16 年前
        1
  •  1
  •   Andrew not the Saint    16 年前

    如果在多次运行(比如1000条记录)中分解更新,对重做和撤消日志的更新量将不会减少。除此之外,与运行单个大型SQL相比,总查询时间可能更高。

    没有真正的方法来解决更新中的撤消/重做日志问题。对于插入和创建表,您可以使用直接的aka append选项,但我想这对您来说并不容易。

        2
  •  1
  •   Mark Brady    16 年前

    取决于行的百分比几乎与数字相同。它还取决于更新是否使行比以前长。也就是说,每行从空到200字节。这可能会对性能链行产生影响。

    不管怎样,你可能想试试这个。

    生成一个新表,该表的列将作为选择的一部分而不是更新进行更正。您可以通过ctas(创建表作为select)构建新表,这可以避免日志记录。

    删除原始表。

    重命名新表。

    重新索引、重新编译反指令、重新生成触发器、重新编译包等。

    这样可以避免很多日志记录。

        3
  •  0
  •   Justin Cave    16 年前

    任何更新都将生成重做。实际上,更新所有行的单个更新将生成最小的重做总量,并在最短的时间内运行。

    假设您正在更新表中的绝大多数行,如果有任何索引使用了列,那么最好在更新之前禁用这些索引,然后在执行大规模更新语句之后使用nologging重新生成这些索引。此外,如果有任何触发器或外键由于更新而需要被激发/验证,那么暂时消除这些触发器或外键可能会有所帮助。