2015-04-28 9 views
5

के माध्यम से योजना की व्याख्या मैं एक गलत xpath की वजह से एक प्रदर्शन मुद्दा था ('@' विशेषता विधेय में लापता) इस तरह एक प्रश्न में:समझना xmltype

चयन extractvalue (क्षेत्र, '// आइटम [attr = " मूल्य "] ') तालिका से जहां फ़ील्ड 1 =: 1;

मैं एक अपवाद की उम्मीद है, लेकिन लगता है कि ओरेकल इस विशेष xpath स्वीकार करते हैं, एक अर्थ है?

मैं एक है कि क्वेरी के खिलाफ योजना की व्याख्या करने का प्रयास किया लेकिन परिणाम बहुत अजीब बात है, किसी की मदद कर सकते हैं मुझे इसे समझने के लिए?

मैं पर्यावरण

SELECT * FROM V$VERSION; 
/* 
Oracle Database 11g Release 11.2.0.3.0 - 64bit Production 
PL/SQL Release 11.2.0.3.0 - Production 
"CORE 11.2.0.3.0 Production" 
TNS for Linux: Version 11.2.0.3.0 - Production 
NLSRTL Version 11.2.0.3.0 - Production 
*/ 

create table TMP_TEST_XML(
    id number, 
content_xml xmltype 
); 
/
create unique index IDX_TMP_TEST_XML on TMP_TEST_XML(id); 
/
declare 
    xml xmltype := xmltype('<root> 
    <a key="A">Aaa</a> 
    <b key="B">Bbb</b> 
    <c key="C">Ccc</c> 
    <d key="D">Ddd</d> 
    <e key="E">Eee</e> 
    <f key="F">Fff</f> 
    <g key="G">Ggg</g> 
    <h key="H">Hhh</h> 
    <i key="I">Iii</i> 
    <l key="L">Lll</l> 
</root>'); 
begin 

    for idx in 1..10000 
    loop 
    insert into TMP_TEST_XML values (idx, xml); 
    end loop; 

    commit; 

end; 
/
--explain plan xpath without '@' (wrong) 
EXPLAIN PLAN SET statement_id = 'planXml1' FOR 
select extractvalue(content_xml, '/root/g[key="G"]') from TMP_TEST_XML where id between 120 and 130; 
/ 
select plan_table_output 
from table(dbms_xplan.display('plan_table',null,'advanced')); 
/
/* 
------------------------------------------------------------------------------------------------ 
| Id | Operation     | Name    | Rows | Bytes | Cost (%CPU)| Time  | 
------------------------------------------------------------------------------------------------ 
| 0 | SELECT STATEMENT   |     | 24 | 48360 |  4 (0)| 00:00:01 | 
| 1 | SORT AGGREGATE    |     |  1 |  4 |   |   | 
| 2 | NESTED LOOPS SEMI   |     | 667K| 2606K| 223K (1)| 00:44:37 | 
| 3 | XPATH EVALUATION   |     |  |  |   |   | 
|* 4 | XPATH EVALUATION   |     |  |  |   |   | 
| 5 | TABLE ACCESS BY INDEX ROWID| TMP_TEST_XML  | 24 | 48360 |  4 (0)| 00:00:01 | 
|* 6 | INDEX RANGE SCAN   | IDX_TMP_TEST_XML | 43 |  |  2 (0)| 00:00:01 | 
------------------------------------------------------------------------------------------------ 
*/ 
/
-- explain plan xpath with '@' (correct) 
EXPLAIN PLAN SET statement_id = 'planXml1' FOR 
select extractvalue(content_xml, '/root/g[@key="G"]') from TMP_TEST_XML where id between 120 and 130; 
/
select plan_table_output 
from table(dbms_xplan.display('plan_table',null,'advanced')); 
/
/* 
------------------------------------------------------------------------------------------------ 
| Id | Operation     | Name    | Rows | Bytes | Cost (%CPU)| Time  | 
------------------------------------------------------------------------------------------------ 
| 0 | SELECT STATEMENT   |     | 24 | 48360 |  4 (0)| 00:00:01 | 
| 1 | SORT AGGREGATE    |     |  1 |  4 |   |   | 
|* 2 | XPATH EVALUATION   |     |  |  |   |   | 
| 3 | TABLE ACCESS BY INDEX ROWID| TMP_TEST_XML  | 24 | 48360 |  4 (0)| 00:00:01 | 
|* 4 | INDEX RANGE SCAN   | IDX_TMP_TEST_XML | 43 |  |  2 (0)| 00:00:01 | 
------------------------------------------------------------------------------------------------ 
*/ 

पुन: पेश करने के लिए पहले से समझाने के लिए एक 'नेस्ट छोरों' (पंक्ति 2) प्रमुखता 667K कि एक दूसरे में गायब हो गया साथ है इस कोड का इस्तेमाल किया। एक ही तालिका में अधिक रिकॉर्ड डालने और एक नया समझाया गया सादा (बिना '@' के) यह मान हमेशा 667K होता है।

यह उस मूल्य का प्रतिनिधित्व कैसे करता है?

उत्तर

1

मुझे अपवाद की उम्मीद है लेकिन ऐसा लगता है कि ओरेकल इस विशेष xpath को स्वीकार करते हैं, इसका अर्थ है?

वैसे, हाँ। अपने आप में, xpath /root/g[key="G"] उस नोड को प्राप्त करता है जिसमें एक बच्चा टैग "कुंजी" और मान "जी" होता है। तो, भले ही extractvalue विफल हो जाएगा (एक से अधिक नोड दिया जाता है), इस काम करेगा:

select extract(xmltype('<root> 
<a key="A">Aaa</a> 
<g key="G"><key>G</key>Ggg</g> 
<h key="H">Hhh</h></root>'),'/root/g[key="G"]').getStringVal() from dual; 

यह रिटर्न <g key="G"><key>G</key>Ggg</g>

उच्च लागत खोज के इस प्रकार में उचित हो सकता है, क्योंकि गुण हैं शायद अन्य प्रकार के उप-नोड्स की तुलना में अधिक अनुकूलित और खोजने योग्य (यह कहने के लिए पर्याप्त हो सकता है कि प्रत्येक टैग के लिए किसी विशेष नाम के साथ केवल एक ही हो सकता है, जबकि टैग कई बार दोहराया जा सकता है)।

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