2017-08-18 42 views
14

हमने हाल ही में ओरेकल 12 सी और हमारे उत्पाद के नवीनतम संस्करण में एक ग्राहक प्रणाली माइग्रेट की है। इस प्रक्रिया में कई माइग्रेशन स्क्रिप्ट चलाना शामिल है जो अधिकतर टेबल जोड़ते या बदलते हैं। हमने देखा है कि एक डिफ़ॉल्ट मान प्रदान करते समय एक तालिका में एक कॉलम जोड़ना, एक अतिरिक्त छुपा कॉलम SYS_NC00002$ बनाता है।ओरेकल यहां एक छुपा कॉलम क्यों जोड़ता है?

आप जब मैं तालिका पॉप्युलेट निम्नलिखित कोड

create table xxx (a integer); 
alter table xxx add (b integer default 1); 

select table_name, column_name, data_type, data_length, column_id, default_length, data_default from user_tab_cols where table_name='XXX'; 

Table_Name|column_Name |data_Type|data_Length|column_Id|default_Length|data_Default| 
------------------------------------------------------------------------------------ 
XXX  |A   |NUMBER |   22|  1|    |   | 
XXX  |SYS_NC00002$|RAW  |  126|   |    |   | 
XXX  |B   |NUMBER |   22|  2|    1|1   | 

के साथ इस पुन: पेश और उस छिपा स्तंभ में मानों को देखने के लिए सक्षम होना चाहिए, वे सभी एक ही कर रहे हैं:

select distinct SYS_NC00002$ from xxx; 

Sys_Nc00002$| 
------------- 
01   | 

आश्चर्यजनक रूप से, जब मैं तुरंत डिफ़ॉल्ट मान सेट नहीं करता हूं लेकिन अतिरिक्त बयान में, कोई अतिरिक्त छुपा कॉलम नहीं बनाया जाता है।

create table xxy (a integer); 
alter table xxy add (b integer); 
alter table xxy modify b default 1; 

select table_name, column_name, data_type, data_length, column_id, default_length, data_default from user_tab_cols where table_name='XXY'; 

Table_Name|column_Name|data_Type|data_Length|column_Id|default_Length|data_Default| 
----------------------------------------------------------------------------------- 
XXY  |A   |NUMBER |   22|  1|    |   | 
XXY  |B   |NUMBER |   22|  2|    1|1   | 

किसी को भी व्याख्या कर सकते हैं क्या यह छिपा स्तंभ के लिए है और यह क्यों केवल पहले उदाहरण में बनाई गई है, लेकिन दूसरे में नहीं है?

+0

बीटीडब्ल्यू, मैं इसे 11 जी – tbone

+0

पर पुन: पेश नहीं कर सकता हूं, मैंने अभी 12 सी पर पुन: उत्पन्न किया है। कोई विचार क्यों नहीं! –

+4

हां, इसे ऑरैकल समर्थन पर मिला https://support.oracle.com/knowledge/Oracle%20Database%20 उत्पाद/2277937_1.html – OutOfMind

उत्तर

3

ओरेकल रिलीज में 11 जी ओरेकल ने डीडीएल संचालन के प्रदर्शन में सुधार के लिए एक नई अनुकूलन तकनीक को घुसपैठ कर दिया है। को मौजूदा तालिका में डिफ़ॉल्ट मान के साथ शून्य कॉलम जोड़ने पर यह नई सुविधा अत्यधिक तेज़ निष्पादन समय की अनुमति देती है। रिलीज 12 सी के बाद से डीडीएल ऑप्टिमाइज़ेशन को NULL कॉलम को डिफ़ॉल्ट मान रखने के लिए बढ़ा दिया गया है।

1.000.000 पंक्तियों के साथ परीक्षण तालिका में निम्नलिखित पर विचार करें:

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 
:

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); 

अब हम एक अतिरिक्त रिक्त नहीं 11g और 12C के लिए अलग-अलग सत्रों में एक डिफ़ॉल्ट मान होने स्तंभ जोड़ने के लिए जा रहे हैं

निष्पादन समय में अंतर पर ध्यान दें: 1 एम पंक्तियां 5 एमएस में अपडेट की गईं!

निष्पादन योजना पता चलता है:

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 

एक नया आंतरिक स्तंभ SYS_NC00006$ से जुड़े एक जटिल विधेय हिस्सा 11g के साथ इसके विपरीत द्वारा 12C शो पर कार्य योजना लागू करके।

यह अनुमान इंगित करता है कि, आंतरिक रूप से, ओरेकल अभी भी बी कॉलम पर विचार कर रहा है ताकि संभावित रूप से गैर डिफ़ॉल्ट मान शामिल हो सकें। इसका मतलब है - पहले ओरेकल डिफ़ॉल्ट रूप से प्रत्येक पंक्ति को भौतिक रूप से अद्यतन नहीं करता है।

क्यों एक नया आंतरिक कॉलम SYS_NC00006$ बनाया गया है?

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    

बी और संबंधित आंतरिक कॉलम के मानों में अंतर पर ध्यान दें। ओरेकल बस अपने सिस्टम जेनरेट किए गए आंतरिक कॉलम (उदा। SYS_NC00006$) और SYS_OP_VECBIT फ़ंक्शन के माध्यम से जांच कर रहा है कि बी कॉलम के डिफ़ॉल्ट मान या एक स्पष्ट डीएमएल कथन के माध्यम से वास्तविक मूल्य को संशोधित करना है या नहीं।

दो अलग-अलग परिवर्तन कथन के साथ क्या है?

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 

नई कॉलम का मूल्य सभी पंक्तियों के लिए शून्य रहता है। कोई वास्तविक अपडेट की आवश्यकता नहीं है इसलिए डीडीएल कथन अनुकूलित नहीं किया जाएगा।

Here एक ओटीएन आलेख है जो नए डीडीएल अनुकूलन को और विस्तार से बताता है।

संबंधित मुद्दे