2011-09-09 10 views
9

मैंने जो दस्तावेज़ पढ़े हैं, उनके अनुसार, सीएलओबी या बीएलओबी के लिए डिफ़ॉल्ट भंडारण इनलाइन है, जिसका अर्थ है कि यदि यह लगभग 4k आकार से कम है तो यह तालिका में आयोजित किया जाएगा।ओरेकल 10 जी छोटे ब्लॉब या क्लोब इनलाइन स्टोर नहीं किया जा रहा है?

लेकिन जब मैं ओरेकल (10.2.0.1.0) में एक डमी टेबल पर इसका परीक्षण करता हूं तो ओरेकल मॉनिटर (ऑलराउंड ऑटोमेशन द्वारा) के प्रदर्शन और प्रतिक्रिया से पता चलता है कि यह तालिका के साथ आयोजित किया जा रहा है।

यहाँ मेरी परीक्षण परिदृश्य है ...

create table clobtest (x int primary key, y clob, z varchar(100)) 
; 
insert into clobtest 
    select object_id, object_name, object_name 
    from all_objects where rownum < 10001 
; 
select COLUMN_NAME, IN_ROW 
from user_lobs 
where table_name = 'CLOBTEST' 
; 

इससे पता चलता है: Y- हाँ (सुझाव है कि ओरेकल पंक्ति में CLOB स्टोर करेगा) इस मामले में

select x, y from CLOBTEST where ROWNUM < 1001 -- 8.49 seconds 
select x, z from CLOBTEST where ROWNUM < 1001 -- 0.298 seconds 

तो, CLOB मूल्यों अधिकतम 30 वर्ण होंगे, इसलिए हमेशा इनलाइन होना चाहिए। यदि मैं ओरेकल मॉनिटर चलाता हूं, तो यह एक LOB.Length दिखाता है जिसके बाद प्रत्येक पंक्ति के लिए LOB.Read() लौटाया जाता है, फिर से यह सुझाव देता है कि क्लोब मान तालिका के साथ होते हैं।

मैं भी इस

create table clobtest 
    (x int primary key, y clob, z varchar(100)) 
    LOB (y) STORE AS  (ENABLE STORAGE IN ROW) 

तरह तालिका बनाने की कोशिश की लेकिन वास्तव में एक ही परिणाम मिला है।

क्या किसी के पास कोई सुझाव है कि मैं तालिका में क्लोब वैल्यू को ऑनलाइन स्टोर करने के लिए ओरेकल को कैसे बल दे सकता हूं (मनाने, प्रोत्साहित)?

अद्यतन (मैं varchar2 स्तंभ जेड पढ़ने के लिए इसी तरह से प्रतिक्रिया समय हासिल करने की उम्मीद कर रहा हूँ): यदि मैं

select COLUMN_NAME, IN_ROW, l.SEGMENT_NAME, SEGMENT_TYPE, BYTES, BLOCKS, EXTENTS 
from user_lobs l 
     JOIN USER_SEGMENTS s 
     on (l.Segment_Name = s. segment_name) 
where table_name = 'CLOBTEST' 

तो यह एसक्यूएल चलाने मैं निम्नलिखित परिणाम ...

Y YES SYS_LOB0000398621C00002$$ LOBSEGMENT 65536 8 1 

उत्तर

0

दो indirections रहे हैं जब यह CLOBs और BLOBs की बात आती है:

  1. LOB मूल्य हो सकता है रों शेष पंक्ति की तुलना में एक अलग डेटाबेस खंड में टोड किया गया।

  2. जब आप पंक्ति से पूछताछ करते हैं, तो परिणाम सेट में केवल गैर-LOB फ़ील्ड्स निहित होते हैं और LOB-fields requries तक पहुंचते हैं क्लाइंट और सर्वर (प्रति पंक्ति!) के बीच एक या अधिक अतिरिक्त राउंड ट्रिप।

मैं काफी आप निष्पादन समय का आकलन कैसे पता नहीं है और मैं Oracle मॉनिटर उपयोग नहीं किया है, लेकिन आप मुख्य रूप से दूसरा अविवेक से प्रभावित हो सकता है। आपके द्वारा उपयोग किए जाने वाले क्लाइंट सॉफ़्टवेयर के आधार पर, राउंड ट्रिप को कम करना संभव है। जैसे जब आप ODP.NET का उपयोग करते हैं, तो पैरामीटर को InitialLobFetchSize कहा जाता है।

अद्यतन:

एक एक बताने के लिए जो दो indirections के लिए प्रासंगिक है, आप 1000 पंक्तियों के साथ अपने LOB क्वेरी दो बार चला सकते हैं। यदि समय पहले से दूसरे भाग में महत्वपूर्ण रूप से गिरता है, तो यह संकेत है 1. दूसरे भाग पर, कैशिंग अलग-अलग डेटाबेस सेगमेंट तक पहुंच जाती है और पहुंच अब बहुत प्रासंगिक नहीं है। यदि समय इसके बारे में रहता है, तो यह दूसरा संकेत है, अर्थात् क्लाइंट और सर्वर के बीच राउंड ट्रिप, जो दो रनों के बीच सुधार नहीं कर सकता है।

एक बहुत ही सरल क्वेरी में 1000 पंक्तियों के लिए 8 सेकंड से अधिक का समय इंगित करता है कि यह संकेत है कि 1000 पंक्तियों के लिए 8 सेकंड वास्तव में डिस्क एक्सेस के साथ समझाया नहीं जा सकता है जब तक कि आपका डेटा बहुत बिखरा हुआ न हो और आपकी डिस्क प्रणाली भारी हो भार।

0

वास्तव में, यह पंक्ति के भीतर संग्रहीत है। आप एक वर्चर के बजाय LOB का उपयोग करने के सरल ओवरहेड से निपटने की संभावना रखते हैं। कुछ भी मुफ़्त नहीं है। डीबी शायद समय से पहले नहीं जानता कि पंक्ति कहां मिलती है, इसलिए शायद यह अभी भी "पॉइंटर का अनुसरण करता है" और LOB बड़ा होने पर अतिरिक्त काम करता है। यदि आप एक वर्कर के साथ मिल सकते हैं, तो आपको चाहिए। 8000 वर्णों से निपटने के लिए 2 वर्कर्स जैसे पुराने हैक भी उच्च प्रदर्शन के साथ आपके व्यावसायिक मामले को हल कर सकते हैं।

LOBS धीमे, पूछने में मुश्किल हैं, आदि सकारात्मक पर, वे 4 जी हो सकते हैं।

उस क्लोब में केवल 4000 बाइट्स को कुछ तोड़ने का प्रयास करना दिलचस्प होगा, और देखें कि प्रदर्शन कैसा दिखता है। शायद यह एक ही गति के बारे में है? यह आपको बताएगा कि यह आपको नीचे धीमा कर रहा है।

चेतावनी, किसी भी समय आपके पीसी पर नेटवर्क यातायात आपको इस तरह के परीक्षणों पर धीमा कर देता है।

गिनती में लपेटकर द्वारा इस कम से कम, इस सर्वर से काम को अलग:

चयन गिनती (*) से (एक्स चयन, वाई clobtest से जहां ROWNUM < 1001)

आप समान प्राप्त कर सकते हैं "सेट ऑटोट ट्रेस" के साथ प्रभाव, लेकिन वहां भी ओवरहेड का पता लगाया जाएगा।

8

ओरेकल LOB का व्यवहार निम्न है।

एक कार्य इनलाइन संग्रहीत होने वाली है:

(
    The value is not NULL 
) AND (
    Its size is higher than 3964 
    OR 
    DISABLE STORAGE IN ROW has been defined in the LOB storage clause 
) 

अब इस मुद्दे को न केवल जो प्रदर्शन प्रभावित हो सकता है:

(
    The size is lower or equal than 3964 
    AND 
    ENABLE STORAGE IN ROW has been defined in the LOB storage clause 
) OR (
    The value is NULL 
) 

एक कार्य आउट-ऑफ-पंक्ति जब संग्रहित है।

यदि LOB अंततः इनलाइन को संग्रहीत नहीं किया जाता है, तो ओरेकल का डिफ़ॉल्ट व्यवहार उन्हें कैशिंग से बचने के लिए है (केवल इनलाइन LOB को पंक्ति के अन्य क्षेत्रों के साथ बफर कैश में कैश किया जाता है)। ओरेकल को गैर रेखांकित LOB को कैश करने के लिए बताने के लिए, जब LOB परिभाषित किया जाता है तो CACHE विकल्प का उपयोग किया जाना चाहिए।

डिफ़ॉल्ट व्यवहार पंक्ति में सक्षम स्टोरेज है, और नोकाच, जिसका अर्थ है कि छोटे LOB को रेखांकित किया जाएगा, बड़े LOBs (और कैश नहीं किए जाएंगे)।

अंत में, संचार प्रोटोकॉल स्तर पर एक प्रदर्शन समस्या भी है। LOB के आकार को पुनः प्राप्त करने और उसके अनुसार स्मृति को आबंटित करने के लिए एक - - डेटा ही (बशर्ते LOB छोटा है)

ये अतिरिक्त roundtrips लाने के लिए एक : ठेठ ओरेकल ग्राहकों उन्हें लाने के लिए LOBs प्रति 2 अतिरिक्त roundtrips प्रदर्शन करेंगे परिणाम प्राप्त करने के लिए एक सरणी इंटरफ़ेस का उपयोग किया जाता है भले ही प्रदर्शन किया जाता है। यदि आप 1000 पंक्तियां पुनर्प्राप्त करते हैं और आपका सरणी आकार काफी बड़ा है, तो आप पंक्तियों को पुनर्प्राप्त करने के लिए 1 राउंडट्रिप और LOBs की सामग्री को पुनर्प्राप्त करने के लिए 2000 राउंडट्रिप्स का भुगतान करेंगे।

कृपया ध्यान दें कि इस तथ्य पर निर्भर करता है कि LOB इनलाइन को संग्रहीत किया गया है या नहीं।वे पूरी तरह से अलग समस्याएं हैं।

प्रोटोकॉल स्तर पर ऑप्टिमाइज़ करने के लिए, ओरेकल ने एक राउंडट्रिप्स (ओसीआईएलओबीएरेरेड) में कई एलओबी लाने के लिए एक नया ओसीआई क्रिया प्रदान किया है। मुझे नहीं पता कि जेडीबीसी के साथ कुछ ऐसा ही मौजूद है या नहीं।

एक और विकल्प क्लाइंट पक्ष पर LOB को बांधना है जैसे कि यह एक बड़ा रॉ/VARCHAR2 था। यह केवल तभी काम करता है जब LOB का अधिकतम आकार परिभाषित किया जा सकता है (क्योंकि अधिकतम आकार बाध्य समय पर प्रदान किया जाना चाहिए)। यह चाल अतिरिक्त राउन्ट्रिप्स से बचाती है: एलओबी को सिर्फ रॉ या वर्चर 2 की तरह संसाधित किया जाता है। हम अपने LOB गहन अनुप्रयोगों में इसका बहुत उपयोग करते हैं।

एक बार राउंडट्रिप्स की संख्या अनुकूलित हो जाने के बाद, स्थिति को बेहतर ढंग से फिट करने के लिए पैकेट आकार (एसडीयू) को शुद्ध कॉन्फ़िगरेशन में आकार दिया जा सकता है (यानी बड़ी संख्या में बड़े राउंडट्रिप्स)। यह "एसक्यूएल * क्लाइंट के लिए नेट अधिक डेटा" और "एसक्यूएल * क्लाइंट से अधिक डेटा नेट" को कम करने की घटनाओं को प्रतीक्षा करता है।

+0

यदि मैं आपको और अधिक बढ़ा सकता हूं तो मैं यह एक शानदार प्रतिक्रिया होगी –

1

यदि आप "वर्कर 2 कॉलम जेड पढ़ने के लिए समान प्रतिक्रिया समय प्राप्त करने की उम्मीद कर रहे हैं", तो आप ज्यादातर मामलों में निराश होंगे। यदि आप एक सीएलओबी का उपयोग कर रहे हैं तो मुझे लगता है कि आपको 4,000 से अधिक बाइट्स स्टोर करना होगा, है ना? फिर यदि आपको अधिक बाइट्स पढ़ने की आवश्यकता है जो अधिक समय ले रहा है।

लेकिन यदि आपके पास कोई मामला है, तो आप एक सीएलओबी का उपयोग करते हैं, लेकिन आप रुचि रखते हैं (कुछ मामलों में) केवल कॉलम (या कम) के पहले 4,000 बाइट्स में, तो आपके पास समान होने का मौका है प्रदर्शन। ऐसा लगता है कि ओरेकल पुनर्प्राप्ति को अनुकूलित कर सकता है यदि आप अपनी तालिका के साथ पंक्ति कैच खंड में DBMS_LOB.SUBSTR और सक्षम स्टोरेज जैसे कुछ का उपयोग करते हैं। उदाहरण:

CREATE TABLE clobtest (x INT PRIMARY KEY, y CLOB) 
LOB (y) STORE AS (ENABLE STORAGE IN ROW CACHE); 

INSERT INTO clobtest VALUES (0, RPAD('a', 4000, 'a')); 
UPDATE clobtest SET y = y || y || y; 
INSERT INTO clobtest SELECT rownum, y FROM all_objects, clobtest WHERE rownum < 1000; 

CREATE TABLE clobtest2 (x INT PRIMARY KEY, z VARCHAR2(4000)); 

INSERT INTO clobtest2 VALUES (0, RPAD('a', 4000, 'a')); 
INSERT INTO clobtest2 SELECT rownum, z FROM all_objects, clobtest2 WHERE rownum < 1000; 

COMMIT; 

10.2.0.4 और 8K ब्लॉक पर अपने परीक्षण में, इन दो प्रश्नों बहुत इसी तरह के प्रदर्शन दे: एसक्यूएल से

SELECT x, DBMS_LOB.SUBSTR(y, 4000) FROM clobtest; 
SELECT x, z FROM clobtest2; 

नमूना * प्लस (मैं प्रश्नों को कई बार भाग गया शारीरिक दूर करने के लिए आईओ के):

SQL> SET AUTOTRACE TRACEONLY STATISTICS 
SQL> SET TIMING ON 
SQL> 
SQL> SELECT x, y FROM clobtest; 

1000 rows selected. 

Elapsed: 00:00:02.96 

Statistics 
------------------------------------------------------ 
      0 recursive calls 
      0 db block gets 
     3008 consistent gets 
      0 physical reads 
      0 redo size 
    559241 bytes sent via SQL*Net to client 
    180350 bytes received via SQL*Net from client 
     2002 SQL*Net roundtrips to/from client 
      0 sorts (memory) 
      0 sorts (disk) 
     1000 rows processed 

SQL> SELECT x, DBMS_LOB.SUBSTR(y, 4000) FROM clobtest; 

1000 rows selected. 

Elapsed: 00:00:00.32 

Statistics 
------------------------------------------------------ 
      0 recursive calls 
      0 db block gets 
     2082 consistent gets 
      0 physical reads 
      0 redo size 
     18993 bytes sent via SQL*Net to client 
     1076 bytes received via SQL*Net from client 
     68 SQL*Net roundtrips to/from client 
      0 sorts (memory) 
      0 sorts (disk) 
     1000 rows processed 

SQL> SELECT x, z FROM clobtest2; 

1000 rows selected. 

Elapsed: 00:00:00.18 

Statistics 
------------------------------------------------------ 
      0 recursive calls 
      0 db block gets 
     1005 consistent gets 
      0 physical reads 
      0 redo size 
     18971 bytes sent via SQL*Net to client 
     1076 bytes received via SQL*Net from client 
     68 SQL*Net roundtrips to/from client 
      0 sorts (memory) 
      0 sorts (disk) 
     1000 rows processed 

आप देख सकते हैं, संगत कर रहे हैं काफी अधिक हो जाता है, लेकिन एसक्यूएल * नेट roundtrips और बाइट्स पिछले दो प्रश्नों में लगभग समान हैं, और कहा कि जाहिरा तौर पर निष्पादन टिम में एक बड़ा फर्क नहीं पड़ता ई!

हालांकि एक चेतावनी: यदि आपके पास बड़े परिणाम सेट हैं, तो लगातार हो सकता है कि आप लगातार बफर कैश में सबकुछ रखने में सक्षम नहीं होंगे और आप बहुत महंगे भौतिक के साथ समाप्त हो जाएंगे पढ़ता है ...

शुभकामनाएँ!

चीयर्स

0

यह महत्वपूर्ण जानकारी (कैसे अतिरिक्त roundtrips बिना LOB पढ़ने के लिए) है, जो Oracle की दस्तावेज़ों में उपलब्ध नहीं है मुझे लगता है कि:

एक अन्य विकल्प ग्राहक के पक्ष LOB बाध्य करने के लिए है जैसे कि यह एक बड़ा रॉ/VARCHAR2 था। यह केवल तभी काम करता है जब LOB का अधिकतम आकार परिभाषित किया जा सकता है (क्योंकि अधिकतम आकार बाध्य समय पर प्रदान किया जाना चाहिए)। यह चाल अतिरिक्त राउन्ट्रिप्स से बचाती है: LOBs को केवल RAW या VARCHAR2 की तरह संसाधित किया जाता है। हम अपने LOB गहन अनुप्रयोगों में इसका बहुत उपयोग करते हैं।

मैं एक ब्लॉब स्तंभ (14KB => पंक्तियों के हजारों) के साथ सरल तालिका (कुछ जीबी) लोड हो रहा है के साथ समस्या थी और मैं एक लंबे समय के लिए यह जांच कर रहा था, नए के लिए (DB_BLOCK_SIZE कार्य भंडारण समस्वरीकरण का एक बहुत कोशिश की टेबलस्पेस, लॉब स्टोरेज विनिर्देश - चंक), sqlnet.ora सेटिंग्स, क्लाइंट प्रीफेचिंग विशेषताओं, लेकिन यह (ओसीसीआई परिणामसेट-> क्लाइंट साइड पर सेटबफरडेटा के साथ लंबे रॉ के रूप में बीएलओबी का इलाज करें) सबसे महत्वपूर्ण बात थी (बिना ब्लॉब कॉलम को तुरंत भेजने के लिए पहली बार में कार्य लोकेटर भेजने और लोड हो रहा है प्रत्येक कार्य लोकेटर के आधार पर अलग से lob।

अब मैं भी ~ 500Mb/एस प्रवाह। (स्तंभों < 3964B के साथ) प्राप्त कर सकते हैं हमारे 14KB ब्लॉब हो जाएगा कई स्तंभों में विभाजित - इसलिए इसे एचडीडी से लगभग अनुक्रमिक पढ़ने के लिए पंक्ति में संग्रहीत किया जाएगा। एक 14 केबी ब्लॉब (एक कॉलम) के साथ मुझे गैर-अनुक्रमिक पढ़ने के कारण ~ 150 एमबी/एस मिलता है (iostat: मर्ज किए गए पढ़ने के अनुरोधों की कम मात्रा)।

नोट: स्थापित करने के लिए मत भूलना भी प्रीफ़ेच आकार/लंबाई lob:

अं = OCIAttrSet (सत्र, (ub4) OCI_HTYPE_SESSION, (शून्य *) & default_lobprefetch_size, 0, (ub4) OCI_ATTR_DEFAULT_LOBPREFETCH_SIZE, त्रुटि);

लेकिन मुझे नहीं पता कि ओडीबीसी कनेक्टर के साथ समान fetching throughput को प्राप्त करना संभव है। मैं बिना किसी सफलता के कोशिश कर रहा था।

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