मेरे पास कुछ एप्लिकेशन लॉगिंग के लिए एक विभाजित तालिका है। कुछ साल पहले, मैंने प्रति माह एक विभाजन के साथ तालिका का विभाजन किया। जैसा कि हम 2016 के करीब हैं, मेरे लिए नए साल के लिए विभाजन जोड़ने का समय आ गया है। विभाजित तालिका में, इसके पिछले दो विभाजनों के रूप में, दिसंबर 2015 के लिए विभाजन और MAXVALUE का उपयोग करने वाला एक विभाजन है। मैं कभी भी MAXVALUE विभाजन में कोई डेटा रखने की योजना नहीं बनाता। यह केवल स्प्लिट पार्टिशन ऑपरेशन को आसान बनाने के लिए है।
अतीत में, मैं निम्नलिखित के समान कमांड के साथ विभाजन जोड़ूंगा:
ALTER TABLE usage_tracking
SPLIT PARTITION usage_tracking_pmax AT (TO_DATE('02/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS))
INTO (PARTITION usage_tracking_p201601, PARTITION usage_tracking_pmax);
ALTER TABLE usage_tracking
SPLIT PARTITION usage_tracking_pmax AT (TO_DATE('03/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS'))
INTO (PARTITION usage_tracking_p201602, PARTITION usage_tracking_pmax);
उपरोक्त SQL कथन MAXVALUE विभाजन को दो विभाजनों में विभाजित करेगा। ऐसे 12 आदेश हैं, प्रत्येक माह के लिए एक।
इस साल, जब मैंने 2016 की स्क्रिप्ट को गैर-उत्पादन वातावरण में चलाने की कोशिश की, तो मुझे यह देखकर आश्चर्य हुआ कि इन आदेशों को पूरा करने में लगभग 30 मिनट का समय लगा। पिछले वर्षों में, उन्होंने सेकंड में पूरा किया। याद रखें कि USAGE_TRACKING_PMAX खाली है इसलिए किसी भी डेटा को उपयुक्त पार्टीशन में ले जाने की आवश्यकता नहीं है।
SPLIT करने वाले मेरे सत्र की गतिविधि का विश्लेषण करने में, मैं स्पष्ट रूप से db फ़ाइल प्रतीक्षा घटनाओं को देख सकता था जिन्हें इस विभाजित तालिका में ट्रैक किया गया था। यह स्पष्ट था कि SPLIT ऑपरेशन अधिकतम विभाजन को पढ़ रहा था, भले ही वह खाली था।
पिछले वर्षों ने ठीक काम किया, लेकिन इस डेटाबेस को हाल ही में Oracle 12c में अपग्रेड किया गया था। मुझे एमओएस नोट 1268714.1 में तेजी से विभाजन विभाजन ऑपरेशन करने के तरीके के बारे में जानकारी मिली, जो कहता है कि यह ओरेकल 10.2.0.3 और उच्चतर पर लागू होता है, लेकिन मेरे पास 11.2.0.4 में कोई समस्या नहीं थी। यह शायद केवल गूंगा भाग्य था और मेरे पास इसे जांचने के लिए 11g डेटाबेस नहीं है क्योंकि मेरे सभी को अपग्रेड कर दिया गया है। इसलिए, जो कुछ बदला है उस पर ध्यान केंद्रित करने के बजाय, मैं केवल समस्या का समाधान करूंगा और अपने दिन को जारी रखूंगा।
एमओएस नोट के अनुसार, इस खाली विभाजन पर तेजी से विभाजित विभाजन करने के लिए, मुझे यह सुनिश्चित करने की ज़रूरत है कि मेरे पास खाली विभाजन पर आंकड़े हैं।
मैंने पुष्टि की है कि इस खाली विभाजन के लिए NUM_ROWS 0 था। इसलिए मुझे विभाजन के आंकड़ों की गणना नहीं करनी पड़ी। मेरा पहला स्प्लिट पार्टिशन ऑपरेशन कुछ ही सेकंड में बहुत तेज था। विभाजन खाली था और Oracle इसे जानता था। मुझे आश्चर्य हुआ कि नया विभाजन, USAGE_TRACKING_P201601 और USAGE_TRACKING_PMAX आंकड़ों के लिए NULL मानों में चला गया। इसका मतलब यह था कि दूसरे नए विभाजन के लिए स्प्लिट पार्टिशन ऑपरेशन करने में काफी समय लगेगा। मेरे कहने का एक उदाहरण यहां दिया गया है। सबसे पहले, हम अधिकतम मान विभाजन में 0 पंक्तियाँ देख सकते हैं।
SQL> select num_rows from dba_tab_partitions
2 where partition_name='USAGE_TRACKING_PMAX';
NUM_ROWS
----------
0
अब मैं उस विभाजन को विभाजित करूँगा।
SQL> ALTER TABLE usage_tracking
2 SPLIT PARTITION usage_tracking_pmax AT ( TO_DATE('02/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS') )
3 INTO (PARTITION usage_tracking_p201601, PARTITION usage_tracking_pmax);
Table altered.
Elapsed: 00:00:03.13
अब ध्यान दें कि पिछले दो विभाजनों में अब कोई आँकड़े नहीं हैं।
SQL> select num_rows from dba_tab_partitions
2 where partition_name='USAGE_TRACKING_PMAX';
NUM_ROWS
----------
SQL> select num_rows from dba_tab_partitions
2 where partition_name='USAGE_TRACKING_P201601';
NUM_ROWS
----------
बिना किसी आंकड़े के, फरवरी 2016 के विभाजन को बनाने के लिए अगला विभाजन विभाजन एक लंबा समय लेता है।
SQL> ALTER TABLE nau_system.usage_tracking
2 SPLIT PARTITION usage_tracking_pmax AT (TO_DATE('03/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS'))
3 INTO (PARTITION usage_tracking_p201602, PARTITION usage_tracking_pmax);
Table altered.
Elapsed: 00:27:41.09
जैसा कि एमओएस नोट कहता है, हमें तेजी से विभाजन ऑपरेशन करने के लिए विभाजन के आंकड़ों की आवश्यकता है। समाधान यह है कि विभाजन पर आँकड़ों की गणना की जाए, और फिर एक बार में सभी विभाजन बनाने के लिए एक ALTER TABLE कमांड का उपयोग किया जाए।
BEGIN
DBMS_STATS.gather_table_stats (tabname=>'USAGE_TRACKING',
partname => 'USAGE_TRACKING_PMAX',
granularity => 'PARTITION');
END;
/
ALTER TABLE usage_tracking
SPLIT PARTITION usage_tracking_pmax INTO
(PARTITION usage_tracking_p201601 VALUES LESS THAN (TO_DATE('02/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
PARTITION usage_tracking_p201602 VALUES LESS THAN (TO_DATE('03/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
PARTITION usage_tracking_p201603 VALUES LESS THAN (TO_DATE('04/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
PARTITION usage_tracking_p201604 VALUES LESS THAN (TO_DATE('05/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
PARTITION usage_tracking_p201605 VALUES LESS THAN (TO_DATE('06/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
PARTITION usage_tracking_p201606 VALUES LESS THAN (TO_DATE('07/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
PARTITION usage_tracking_p201607 VALUES LESS THAN (TO_DATE('08/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
PARTITION usage_tracking_p201608 VALUES LESS THAN (TO_DATE('09/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
PARTITION usage_tracking_p201609 VALUES LESS THAN (TO_DATE('10/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS') ),
PARTITION usage_tracking_p201610 VALUES LESS THAN (TO_DATE('11/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS') ),
PARTITION usage_tracking_p201611 VALUES LESS THAN (TO_DATE('12/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS') ),
PARTITION usage_tracking_p201612 VALUES LESS THAN (TO_DATE('01/01/2017 00:00:00','MM/DD/YYYY HH24:MI:SS') ),
PARTITION usage_tracking_pmax);
अगर मैं 12 अलग-अलग विभाजन विभाजन संचालन करने के लिए स्क्रिप्ट छोड़ देता, तो मुझे प्रत्येक के बीच अधिकतम विभाजन पर आंकड़ों की पुनर्गणना करने की आवश्यकता होती। एक कमांड का उपयोग करना अधिक कुशल था।