Dalam rilis Oracle 11g Oracle telah memperkenalkan teknik optimasi baru untuk meningkatkan kinerja operasi DDL. Fitur baru ini memungkinkan waktu eksekusi yang sangat cepat saat menambahkan NOT NULL kolom dengan nilai default ke tabel yang ada. Sejak rilis 12c, pengoptimalan DDL telah diperluas untuk menyertakan NULL kolom yang memiliki nilai default.
Pertimbangkan tabel pengujian berikut dengan 1.000.000 baris:
sql> create table xxy
as select rownum a from dual connect by level <= 1e6
;
sql> select /*+ gather_plan_statistics */ count(1) from xxy;
sql> select * from table(dbms_xplan.display_cursor);
Sekarang kita akan menambahkan kolom bukan nol ekstra yang memiliki nilai default di sesi yang berbeda untuk 11g dan 12c:
11g> alter table xxy add b number default 1;
--Table XXY altered. Elapsed: 00:01:00.998
12c> alter table xxy add b number default 1;
--Table XXY altered. Elapsed: 00:00:00.052
Perhatikan perbedaan dalam waktu eksekusi:1 juta baris diperbarui dalam 5 md!?
Rencana eksekusi menunjukkan:
11g> select count(1) from xxy where b = 1;
COUNT(1)
----------
1000000
11g> select * from table(dbms_xplan.display_cursor);
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1040 (100)| |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
|* 2 | TABLE ACCESS FULL| XXY | 898K| 11M| 1040 (1)| 00:00:13 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("B"=1)
Note
-----
- dynamic sampling used for this statement (level=2)
12c> select count(1) from xxy where b = 1;
12c> select * from table(dbms_xplan.display_cursor);
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 429 (100)| |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
|* 2 | TABLE ACCESS FULL| XXY | 1000K| 4882K| 429 (2)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(DECODE(TO_CHAR(SYS_OP_VECBIT("SYS_NC00002$",0)),NULL,NVL("
B",1),'0',NVL("B",1),'1',"B")=1)
Note
-----
- statistics feedback used for this statement
Rencana eksekusi pada 12c menunjukkan kontras dengan 11g bagian predikat kompleks yang melibatkan kolom internal baru SYS_NC00006$
.
Predikat ini menunjukkan bahwa, secara internal, Oracle masih mempertimbangkan kolom B berpotensi dapat memuat nilai non-default. Artinya - Oracle pada awalnya tidak secara fisik memperbarui setiap baris dengan nilai default.
Mengapa kolom internal baru SYS_NC00006$
dibuat?
12c> select column_name, virtual_column, hidden_column, user_generated
from user_tab_cols
where table_name = 'XXY'
;
COLUMN_NAME VIR HID USE
---------------- --- --- ---
B NO NO YES
SYS_NC00002$ NO YES NO
A NO NO YES
12c> select a, b, SYS_NC00002$ hid from xxy where a in (1,10);
A B HID
---------- ---------- ----------------
1 1
10 1
12c> update xxy set b=1 where a=10 and b=1;
1 row updated.
12c> select a, b, SYS_NC00002$ hid from xxy where a in (1,10);
A B HID
---------- ---------- ----------------
1 1
10 1 01
Perhatikan perbedaan nilai B dan kolom internal terkait. Oracle hanya memeriksa melalui kolom internal yang dihasilkan sistemnya (mis. SYS_NC00006$
) dan melalui SYS_OP_VECBIT
berfungsi apakah akan mempertimbangkan nilai default kolom B atau nilai sebenarnya yang dimodifikasi melalui pernyataan DML eksplisit.
Ada apa dengan dua pernyataan alter yang terpisah?
12c> alter table xxy add (b integer);
12c> alter table xxy modify b default 1;
12c> select count(b), count(coalesce(b,0)) nulls from xxy where b = 1 or b is null;
COUNT(B) NULLS
---------- ----------
0 1000000
Nilai kolom baru tetap NULL untuk semua baris. Tidak ada pembaruan nyata yang diperlukan oleh karena itu pernyataan DDL tidak akan dioptimalkan.
Di sini adalah artikel OTN yang menjelaskan optimasi DDL baru secara lebih rinci.