侧边栏壁纸
博主头像
与晚风述往事博主等级

万般皆下品,唯有读书高。

  • 累计撰写 149 篇文章
  • 累计创建 29 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

CREATE TABLE ... AS(CTAS)优化

与晚风述往事
2022-03-04 / 0 评论 / 0 点赞 / 206 阅读 / 2,188 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-03-04,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

介绍

在Oracle数据库中,我们需要做测试时,通常会使用CREATE TABLE ... AS先将表中的数据备份成一张临时表(以下简称为CTAS)。对于小表来说,这种执行时间很短,但是对于诸如几百万、上千万这样的大表,这种操作就会变得很慢(使用机械硬盘的情况下,固态硬盘的话,创建时间可能不会让你觉得难以接受)。另外说明一下,这里说的几百万、上千万的表是指那种占用空间比较大的,如果你的字段和字段长度都比较小,则性能也不会慢到无法接受的地步。

遇到这种情况的时候,我们不着急的话就可以在旁边玩会儿手机、打会儿游戏,如果比较着急的话,就必须得使用点特殊方法让它执行的更快才行。

Oracle的官方文档上介绍了两种方法提高CTAS的速度,分别是:

  • 并行创建
  • 创建时生成最少的重做日志

这两种方法的原理我们简单了解一下吧!

并行创建

Oracle在对大表进行CTAS时,可以通过使用“NOLOGGING”关键字来指定创建时使用并行。并行简单的理解就是使用多个进程执行表创建,自然会比单个进程执行的效率更高。

我们要了解并行创建表原理的话,首先需要知道Oracle执行CTAS具体做了啥操作。CTAS执行时,会分成两部分。首先是查询原表中的数据,查询到数据后,再将结果数据插入到新的表中。在使用并行时,Oracle会根据以下情况,去选择要并行的部分:

  • 创建表(DDL)部分会被并行:

    • CREATE TABLE ... AS 语句包含“PARALLEL”关键字
    • 使用“ALTER SESSION FORCE PARALLEL DDL”语句指定会话内并行所有DDL语句
  • 查询(SELECT)部分会被并行:

    • 查询语句中加“PARALLEL”或“PARALLEL_INDEX”关键字、CREATE部分中包含“PARALLEL”子句和查询中引用的模式对象中有一个与其关联的“PARALLEL”参数时。
    • 查询中指定的至少一个表需要全表扫描或跨越多个分区的索引范围扫描。

注意,如果创建表时指定了“PARALLEL”并行执行,则该表的任何后续DML或查询语句都会去尝试使用并行执行。除此之外,使用并行创建表会导致CPU的升高,尽量在业务不繁忙的情况下使用。

创建时生成最少的重做日志

优化CTAS的另一个方法就是在创建表时,使用“NOLOGGING”关键字。指定关键字后,Oracle会在创建表时生成最少的重做日志。从优化的角度来讲,这具有以下优点:

  • 创建表时,重做日志(redo log)的空间使用的更少
  • 减少了创建表所需要的时间
  • 提升并行创建大型表的性能

除此之外,指定“NOLOGGING”关键字还会影响到之后使用SQL*Loader和直接路径插入该表时,同样生成最少的重做日志。注意,后续的DML语句(例如UPDATE、DELETE和常规INSERT语句)不受表的NOLOGGING属性和generate redo的影响。

通常来说,对于较大型的表,指定“NOLOGGING”关键字优化的性能要大于小型表。对于小型表来说,指定“NOLOGGING”关键字对创建表时的性能影响不大,但是,对于较大的表,性能改进会非常明显,尤其是在并行创建表的时候。

案例

理论说到这里已经差不多了,接下来就做几个实验来证明上面所写的内容。

测试过程中使用的表来自于生产环境中,数据量有4956775,表占用大小是1.06G左右。

说明,下面的每项测试执行十次,取执行时间最短的结果。

常规的CTAS

首先是测试什么参数都不加的CTAS,也就是常规的CTAS语句。

create table TEST_1
as
select * from TEST_0;

执行结果如下:
image.png
从图中看到,常规CTAS的执行时间是3.585s。

带NOLOGGING的CTAS

测试完常规的CTAS后,我们接着测试最少重做(redo)的CTAS。

create table TEST_2 nologging
as
select * from TEST_0;

执行结果如下:
image.png
从图中看到,重做日志减少后,CTAS的性能已经有了一点点提升。

带PARALLEL的CTAS

测试了减少重做方法后,继续测试并行执行的CTAS。

create table TEST_3 parallel
as
select * from TEST_0;

执行结果如下:
image.png
从图中看到,使用并行后,性能较常规CTAS已经有了大幅度的提升。

带PARALLEL和NOLOGGING的CTAS

最后,我们测试一下并行且减少重做日志的CTAS性能如何。

create table TEST_4 parallel nologging
as
select * from TEST_0;

执行结果如下:
image.png
从图中看到,同时使用这两种方法后,SQL的性能提升非常夸张,由常规CTAS的3.585s提升到了1.082s。

结论

看到这里,你们可能会觉得这也没啥啊,就提升了3倍左右的性能。我要告诉你的是,从300s到10s,要比你从6s优化到3s容易的多,到了个位数后,每加快一点时间就是无比艰难。

最后,建议在创建表时,根据实际情况去选择使用的SQL语句。如果你的业务处于繁忙的状态或者是想以最小影响的情况去创建表,就只用减少重做日志的方式创建表即可;反之,业务不繁忙或者不在乎CPU的影响,就使用“PARALLEL”和“NOLOGGING”的CTAS的方式创建,最大化的优化速度。对于大型表,强烈建议使用“PARALLEL”和“NOLOGGING”的CTAS方式。

0

评论区