将日期时间串联到时间戳中

时间:2018-10-27 12:21:54

标签: oracle performance oracle12c sql-tuning

Oracle 12C,未分区,没有ASM。

这是背景。我有一个包含多列的表,其中三列是-

TRAN_DATE                             DATE
TRAN_TIME                             TIMESTAMP(6)
FINAL_DATETIME                        NOT NULL TIMESTAMP(6)

该表有大约7,000万条记录。我想做的是将tran_date和tran_time字段连接起来,并用该输出更新final_datetime字段,以获取所有7000万条记录。

这是我的查询-

update MYSCHEMA.MYTAB set FINAL_DATETIME = (to_timestamp( (to_char(tran_date, 'YYYY/MM/DD') || ' ' ||to_char(TRAN_TIME,'HH24MISS') ), 'YYYY-MM-DD HH24:MI:SS.FF'))

例如:

目前(一项记录)

TRAN_DATE=01-DEC-16
TRAN_TIME=01-JAN-70 12.35.58.000000 AM    /*I need only the time part from this*/
FINAL_DATETIME=22-OCT-18 04.37.18.870000 PM

发布查询-FINAL_DATETIME必须为

01-DEC-16 12.35.58.000000 AM

to_timestamp确实需要2个字符串,我担心这会大大降低更新速度。有什么建议吗?

我还能做些什么来提高性能?目前没有人会使用表格,因此,我确实可以选择

  • 下降指数
  • 关闭日志记录

    还有其他任何人可以建议的内容。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

我希望使用CTAS方法,如果您的表上没有索引,触发器和约束,那么您的工作会更简单。

为要修改的列创建一个新表。

CREATE TABLE mytab_new
NOLOGGING
     AS
      SELECT /*+ FULL(mytab) PARALLEL(mytab, 10) */ --hint to speed up the select.
       CAST(tran_date AS TIMESTAMP) + ( tran_time - trunc(tran_time) ) AS final_datetime
          FROM mytab;

我在新表中仅包含一个(最后一个)列,因为将另外两个存储在新表中会浪费资源。除了两个现在多余的列之外,您还可以在select中包括其他列。

阅读logging/nologging,以了解选择中的NOLOGGING选项。

下一步是使用new_mytab中其他列的定义重建新表mytab的索引,触发器和约束。

然后重命名表

rename mytab     to mytab_bkp;

rename mytab_new to mytab;

您可以在验证新表之后删除表mytab_bkp,或者稍后在感觉不再需要它时将其删除。

Demo