Ich hatte ein Performance-Problem durch eine falsche XPath verursacht ('@' fehlt in Attribut Prädikat) in einer Abfrage wie folgt aus:Verständnis erklären Plan durch xmltype
wählen ExtractValue (Feld, ‚// item [attr =“ Wert "] ') aus Tabelle, wo field1 =: 1;
Ich erwartete eine Ausnahme aber scheint, dass Oracle diesen bestimmten XPath akzeptieren, hat eine Bedeutung?
Ich habe versucht, einen Plan gegen diese Abfrage auszuführen, aber das Ergebnis ist ziemlich seltsam, kann jemand mir helfen, es zu verstehen?
verwenden ich diesen Code der Umwelt
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 |
------------------------------------------------------------------------------------------------
*/
Im ersten erkläre es eine ‚verschachtelte Schleifen‘ ist (Zeile 2) mit 667 T Kardinalität zu reproduzieren, die in dem zweiten verschwunden. Wenn Sie mehr Datensätze in dieselbe Tabelle einfügen und eine neue EXPLAIN-Ebene (ohne '@') ausführen, ist dieser Wert immer 667K.
Was bedeutet dieser Wert?