为什么CREATE TABLE AS SELECT比使用SELECT

时间:2018-07-19 22:09:20

标签: sql oracle11g sql-insert create-table

我使用INNER JOIN进行查询,结果为1200万行。 我喜欢把它放在桌子上。 我做了一些测试,当我使用AS SELECT子句创建表时,比先创建表并在运行SELECT之后运行INSERT更快。 我不明白为什么。 有人可以为我解释吗? Tks

2 个答案:

答案 0 :(得分:1)

使用SELECT STATEMENT创建的表没有主键,索引,标识...列始终允许为NULL。 并且不必将其写入事务日志(因此不会回滚)。好像是“裸表”。

使用INSERT ... SELECT,必须先创建表,然后在创建表时可以定义键,索引,标识...,它将使用事务日志 当应用于大量数据时,它非常慢。

答案 1 :(得分:1)

如果您使用“创建表作为选择”(CTAS)

CREATE TABLE new_table AS 
    SELECT * 
    FROM old_table

您会自动对数据进行 direct-path insert 。如果您进行

INSERT INTO new_table AS 
    SELECT * 
    FROM old_table

您进行常规插入。如果要执行直接路径插入,则必须使用APPEND提示。所以你必须要做

INSERT /*+ APPEND */ INTO new_table AS 
    SELECT * 
    FROM old_table

获得与“在创建表中进行选择时相似”的性能。

常规的常规插入件如何工作?

Oracle检查表的 free list 中是否有可用空间的表段块。如果该块不在缓冲区高速缓存中,则将其读入缓冲区高速缓存。最终,该块被读回到磁盘。 在此过程中,写入该块的撤消操作(此处仅需要少量数据),例如,更新数据结构。必要时,段头中包含的空闲列表,所有这些更改也将写入重做缓冲区。

直接路径插入如何工作?

该过程在表的高水位标记上方分配空间,即超出已使用的空间。它将数据直接写入磁盘,而无需使用缓冲区高速缓存。并且还将其写入重做缓冲区。提交会话后,高水位标记将超出新的书面数据,并且其他会话现在可以看到该数据。

如何改善CTAS和直接路径插入?

  • 您可以在NOLOGGING模式下创建故事,而不写入任何重做信息。如果这样做,则应在插入后对包含该表的表空间进行备份,否则,如果需要,将无法恢复该表。
  • 您可以并行进行选择

  • 您可以并行插入

  • 如果在插入操作期间必须维护索引和约束甚至触发器,则可能会大大降低插入操作的速度。因此,您应该避免这种情况,并在插入之后创建索引,并可能使用novalidata创建约束。