我使用INNER JOIN进行查询,结果为1200万行。 我喜欢把它放在桌子上。 我做了一些测试,当我使用AS SELECT子句创建表时,比先创建表并在运行SELECT之后运行INSERT更快。 我不明白为什么。 有人可以为我解释吗? Tks
答案 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和直接路径插入?
您可以并行进行选择
您可以并行插入
如果在插入操作期间必须维护索引和约束甚至触发器,则可能会大大降低插入操作的速度。因此,您应该避免这种情况,并在插入之后创建索引,并可能使用novalidata创建约束。