Oracle XMLIndex - 进行范围搜索

时间:2014-06-16 14:08:57

标签: oracle xmltype xmlindex

我将我的xml数据存储在Oracle XMLType列中,我希望能够对xml内的数字进行范围搜索。

我认为Oracle支持这种操作,但谷歌搜索并没有帮助我。我应该如何创建XMLIndex和范围搜索查询?

示例表:

CREATE TABLE XMLDBTEST.XML_TABLE
(
  CONTENT  SYS.XMLTYPE
)
XMLTYPE CONTENT STORE AS BINARY XML

示例数据:

<person>
    <name>feyyaz</name>
    <age>28</age>
</person>

<person>
    <name>ahmet</name>
    <age>26</age>
</person>

<person>
    <name>mehmet</name>
    <age>20</age>
</person>

1 个答案:

答案 0 :(得分:1)

创建表格和示例数据

CREATE TABLE XML_TABLE
(
  CONTENT  SYS.XMLTYPE
)
XMLTYPE CONTENT STORE AS BINARY XML;

insert into xml_table values(xmltype('
<persons>
    <person>
        <name>feyyaz</name>
        <age>28</age>
    </person>
    <person>
        <name>ahmet</name>
        <age>26</age>
    </person>
    <person>
        <name>mehmet</name>
        <age>20</age>
    </person>
</persons>'
));

commit;

创建XMLIndex

create index xml_table_ix on xml_table(content)
indextype is xdb.xmlindex
parameters ('PATHS (INCLUDE(/persons/person/age))');

查询年龄

select name, age
from xml_table
cross join
xmltable
(
    '/persons/person'
    passing xml_table.content
    columns
        name varchar2(100) path 'name',
        age  number        path 'age'
)
where age = 20;

NAME    AGE
----    ---
mehmet   20

解释显示索引访问权限的计划

explain plan for
select name, age
from xml_table
cross join
xmltable
(
    '/persons/person'
    passing xml_table.content
    columns
        name varchar2(100) path 'name',
        age  number        path 'age'
)
where age = 20;

select * from table(dbms_xplan.display);

Plan hash value: 2259392803

----------------------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name                           | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |                                |     1 |  3536 |     6   (0)| 00:00:01 |
|*  1 |  FILTER                       |                                |       |       |            |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID | SYS2970790_XML_TABL_PATH_TABLE |     1 |  3524 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN           | SYS2970790_XML_TABL_PIKEY_IX   |     1 |       |     1   (0)| 00:00:01 |
|*  4 |  FILTER                       |                                |       |       |            |          |
|   5 |   NESTED LOOPS                |                                |     1 |  3536 |     4   (0)| 00:00:01 |
|*  6 |    TABLE ACCESS FULL          | SYS2970790_XML_TABL_PATH_TABLE |     1 |  3524 |     3   (0)| 00:00:01 |
|   7 |    TABLE ACCESS BY USER ROWID | XML_TABLE                      |     1 |    12 |     1   (0)| 00:00:01 |
|*  8 |   FILTER                      |                                |       |       |            |          |
|*  9 |    TABLE ACCESS BY INDEX ROWID| SYS2970790_XML_TABL_PATH_TABLE |     1 |  3524 |     2   (0)| 00:00:01 |
|* 10 |     INDEX RANGE SCAN          | SYS2970790_XML_TABL_PIKEY_IX   |     1 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(:B1<SYS_ORDERKEY_MAXCHILD(:B2))
   2 - filter(SYS_XMLI_LOC_ISNODE("SYS_P3"."LOCATOR")=1)
   3 - access("SYS_P3"."RID"=:B1 AND "SYS_P3"."PATHID"=HEXTORAW('38DE')  AND "SYS_P3"."ORDER_KEY">:B2 
              AND "SYS_P3"."ORDER_KEY"<SYS_ORDERKEY_MAXCHILD(:B3))
       filter(SYS_ORDERKEY_DEPTH("SYS_P3"."ORDER_KEY")=SYS_ORDERKEY_DEPTH(:B1)+1)
   4 - filter(CAST( (SELECT "SYS_P6"."VALUE" FROM "JHELLER_DBA"."SYS2970790_XML_TABL_PATH_TABLE" 
              "SYS_P6" WHERE :B1<SYS_ORDERKEY_MAXCHILD(:B2) AND "SYS_P6"."ORDER_KEY"<SYS_ORDERKEY_MAXCHILD(:B3) AND 
              "SYS_P6"."ORDER_KEY">:B4 AND "SYS_P6"."PATHID"=HEXTORAW('38DE')  AND "SYS_P6"."RID"=:B5 AND 
              SYS_XMLI_LOC_ISNODE("SYS_P6"."LOCATOR")=1 AND SYS_ORDERKEY_DEPTH("SYS_P6"."ORDER_KEY")=SYS_ORDERKEY_DEPT
              H(:B6)+1) AS number        )=20)
   6 - filter("SYS_P1"."PATHID"=HEXTORAW('2BA3')  AND SYS_XMLI_LOC_ISNODE("SYS_P1"."LOCATOR")=1)
   8 - filter(:B1<SYS_ORDERKEY_MAXCHILD(:B2))
   9 - filter(SYS_XMLI_LOC_ISNODE("SYS_P6"."LOCATOR")=1)
  10 - access("SYS_P6"."RID"=:B1 AND "SYS_P6"."PATHID"=HEXTORAW('38DE')  AND "SYS_P6"."ORDER_KEY">:B2 
              AND "SYS_P6"."ORDER_KEY"<SYS_ORDERKEY_MAXCHILD(:B3))
       filter(SYS_ORDERKEY_DEPTH("SYS_P6"."ORDER_KEY")=SYS_ORDERKEY_DEPTH(:B1)+1)

Note
-----
   - dynamic sampling used for this statement (level=2)
   - automatic DOP: skipped because of IO calibrate statistics are missing