Overview
The CREATE TABLE ... AS
SELECT statement (CTAS) is a powerful tool for manipulating large sets of
data. CTAS provides a mechanism for efficiently executing a SQL query and storing the
results of that query in a new database table.
The INSERT /*+APPEND */ ...
AS SELECT statement offers the same capabilities with existing
database tables.
APPEND into Tables
By using the APPEND hint, you ensure that Oracle always grabs
"fresh" data blocks by raising the high-water-mark for the table. If you are doing
parallel insert DML, the Append mode is the default and you don't need to specify an
APPEND hint.
When you use the APPEND hint for INSERT, data is simply appended to
a table above the HWM which has the effect of not creating UNDO. Existing free space in
blocks is not used.
High Water Mark
The high water mark is the boundary between used and unused space
in a segment. As requests for new free blocks that cannot be satisfied by existing free
lists are received, the block to which the high water mark points becomes a used block,
and the high water mark is advanced to the next block. In other words, the segment space
to the left of the high water mark is used, and the space to the right of it is
unused.
Suggest Way for fast INSERTs
- Mark indexes unuasble
- Disable primary key
- Alter table nologging
- Do an insert /*+ append */ into table (select ..)
- Enable primary key
- Rebuild indexes nologging
Example
create table bigtab
as
select rownum id, a.*
from all_objects a
where 1=0;
alter table bigtab nologging;
declare
l_cnt number;
l_rows number := 1000000;
begin
insert /*+ append */
into bigtab
select rownum, a.*
from all_objects a;
l_cnt := sql%rowcount;
commit;
while (l_cnt < l_rows)
loop
insert /*+ APPEND */ into bigtab
select rownum+l_cnt,
OWNER, OBJECT_NAME, SUBOBJECT_NAME,
OBJECT_ID, DATA_OBJECT_ID,
OBJECT_TYPE, CREATED, LAST_DDL_TIME,
TIMESTAMP, STATUS, TEMPORARY,
GENERATED, SECONDARY
from bigtab
where rownum <= l_rows-l_cnt;
l_cnt := l_cnt + sql%rowcount;
commit;
end loop;
end;
/
Now we have a Table with 1'000'000 Rows. Now delete some Rows, to
force Oracle to refill this freespace using the FREELISTS in a normal INSERT. However in
APPEND Mode the FREELISTS are not used and the freespace are not reoccupied.
DELETE FROM bigtab WHERE id between 1000 and
2500;
DELETE FROM bigtab WHERE id between 3500 and 6500;
DELETE FROM bigtab WHERE id between 15000 and 20000;
DELETE FROM bigtab WHERE id between 350000 and 370000;
COMMIT;
CREATE TABLE insert_test AS SELECT * FROM bigtab;
SQL> CREATE TABLE insert_test AS SELECT * FROM
bigtab;
Table created.
SQL> INSERT INTO insert_test SELECT rownum, a.* FROM all_objects a;
49483 rows created.
Elapsed: 00:00:03.92 <==================== !
SQL> DROP TABLE insert_test;
Table dropped.
SQL> CREATE TABLE insert_test AS SELECT * FROM
bigtab;
Table created.
SQL> ALTER TABLE insert_test NOLOGGING;
Table altered.
SQL> INSERT /*+ append */ INTO insert_test SELECT rownum, a.* FROM all_objects
a;
49483 rows created.
Elapsed: 00:00:02.54 <==================== !
As you can see, only to insert about 50'000 Rows, the APPEND Insert
is much faster, due the free space in the Oracle blocks are not refilled, the Rows are
appended and the Highwater Mark is moved.
|