Examples of using indexes with queries that specify fn:starts-with
Starting in version 10.1, for queries with predicates that contain the fn:starts-with function, the optimizer can choose to use a VARCHAR-type index to speed up the query.
No changes are necessary to existing VARCHAR indexes, and you do not need to use any special syntax in the CREATE INDEX statement when you create new VARCHAR indexes.
The fn:starts-with function determines whether a string begins with a specific substring.
Creating a VARCHAR type index
This example demonstrates how to create a table with an XML column, insert data into it, and create an index of VARCHAR type.
First, create
the table called FAVORITE_CDS, which has a column called CDINFO that
is of type XML:
CREATE TABLE favorite_cds (
NAME CHAR(20) NOT NULL,
CDID BIGINT,
CDINFO XML
);
Insert a record into the FAVORITE_CDS table:
INSERT INTO favorite_cds VALUES('John Peterson', 01,
'<FAVORITECDS>
<CD>
<TITLE>Top hits</TITLE>
<ARTIST>Good Singer</ARTIST>
<COMPANY>Top Records</COMPANY>
<YEAR>1999</YEAR>
</CD>
<CD>
<TITLE>More top hits</TITLE>
<ARTIST>Better Singer</ARTIST>
<COMPANY>Better Music </COMPANY>
<YEAR>2005</YEAR>
</CD>
<CD>
<TITLE>Even more top hits</TITLE>
<ARTIST>Best Singer</ARTIST>
<COMPANY>Best Music</COMPANY>
<YEAR>2010</YEAR>
</CD>
</FAVORITECDS>');
You can create a VARCHAR
index, for example called year_idx, on the
/FAVORITECDS/CD/YEAR
path,
for example:CREATE INDEX year_idx ON favorite_cds (cdinfo)
GENERATE KEYS USING XMLPATTERN '/FAVORITECDS/CD/YEAR'
AS SQL VARCHAR(20);
You can also create a VARCHAR
index, for example called company_idx, on the
/FAVORITECDS/CD/COMPANY
path.
The following example creates a case insensitive index on company
name by using the fn:upper-case function:CREATE INDEX company_idx ON favorite_cds (cdinfo)
GENERATE KEYS USING XMLPATTERN '/FAVORITECDS/CD/COMPANY/fn:upper-case(.)'
AS SQL VARCHAR(20);
Running queries that have predicates containing fn:starts-with
For the following query, the optimizer might choose to
use the VARCHAR index, year_idx, instead of performing a table
scan to find CDs from the 1990s (in this example, the fn:starts-with
function finds CDs having a year that starts with 199). The optimizer
can choose to use the year_idx index, if it is found to be
cheaper.
XQUERY for $y in db2-fn:xmlcolumn
('FAVORITE_CDS.CDINFO')/FAVORITECDS/CD/YEAR
[fn:starts-with(., "199")]/.. return $y
--------------------------------
<CD>
<TITLE>Top hits</TITLE>
<ARTIST>Good Singer</ARTIST>
<COMPANY>Top Records</COMPANY>
<YEAR>1999</YEAR>
</CD>
1 record(s) selected.
Note that queries written
in a format where you specify a context item expression (.) for the
first parameter of the fn:starts-with function enable the optimizer
to choose only one index scan, whereas other formats might require
two index scans. For this reason, a similar query written in the following
format will likely run more slowly:
XQUERY for $y in db2-fn:xmlcolumn
('FAVORITE_CDS.CDINFO')/FAVORITECDS/CD
[fn:starts-with(YEAR, "199")] return $y
For the next query, the optimizer might choose to use
the VARCHAR index, company_idx, instead of performing a table
scan to find records where the company name starts with BES. The optimizer
can choose to use the company_idx index, if it is found to
be cheaper.
XQUERY for $y in db2-fn:xmlcolumn
('FAVORITE_CDS.CDINFO')/FAVORITECDS/CD/COMPANY
[fn:starts-with(fn:upper-case(.), "BES")]/.. return $y
--------------------------------
<CD>
<TITLE>Even more top hits</TITLE>
<ARTIST>Best Singer</ARTIST>
<COMPANY>Best Music</COMPANY>
<YEAR>2010</YEAR>
</CD>
1 record(s) selected.