Khai thác các chỉ mục XML để tăng hiệu năng truy vấn XML trong DB2 9
Matthias Nicola, Chuyên gia DB2 , IBM Silicon Valley Laboratory
Tóm tắt: DB2® 9 đảm bảo lưu trữ pureXML và cung cấp XQuery và SQL/XML
như là các ngôn ngữ truy vấn. Các chỉ mục XML rất cần thiết cho hiệu suất truy
vấn cao, nhưng việc sử dụng chúng để đánh giá truy vấn phụ thuộc vào cách tạo
nên các vị từ truy vấn. Bài viết này trình bày một tập các hướng dẫn để viết các
truy vấn XML và tạo các chỉ mục XML một cách phù hợp để cho các chỉ mục
tăng tốc độ truy vấn của bạn như mong muốn. Ngoài ra học để tìm kiếm trong các
kế hoạch thực hiện truy vấn XML nhằm phát hiện các vấn đề hiệu năng và tìm ra
cách sửa chữa chúng. Một "cẩm nang" ("cheat sheet") có thể tải về tóm tắt các
hướng dẫn quan trọng nhất. [30.07.2009: Bài viết này đã được cập nhật cho DB2
9.5 và 9.7, trong đó có thêm các truy vấn thí dụ SQL/XML.--Biên tập.]
Giới thiệu
DB2 9 cung cấp lưu trữ pureXML, cùng với các chỉ mục XML, XQuery và
SQL/XML như ngôn ngữ truy vấn, hỗ trợ lược đồ XML, các mở rộng XML đến
các tiện ích như: Nhập/Xuất và Chạy báo cáo trạng thái (Runstats). Cũng như đối
với các truy vấn quan hệ, các chỉ mục là điều quyết định đối với hiệu suất cao của
XQuery và các câu lệnh SQL/XML của bạn. DB2 cho phép bạn định nghĩa các chỉ
mục XML với đường dẫn cụ thể trên các cột XML. Điều đó có nghĩa bạn có thể sử
dụng chúng để đánh chỉ mục các phần tử và các thuộc tính được chọn, thường
được sử dụng trong các vị từ và các phép kết nối. Ví dụ, khi sử dụng dữ liệu mẫu
trong Hình 1, chỉ mục sau là idx1 sẽ có ích cho việc tìm kiếm bảng và các kết nối
dựa vào các định danh (ID) tác giả trên tất cả các tài liệu trong cột XML bookinfo
của bảng books.
create table books(bookinfo XML);
create index idx1 on books(bookinfo)
generate keys using xmlpattern
'/book/authors/author/@id'
as sql double;
Hình 1. Tài liệu XML thí dụ theo định dạng văn bản (tuần tự) và định dạng
(phân cấp) đã được phân tích
Do DB2 khơng bắt buộc bạn phải kết hợp một lược đồ XML đơn với tất cả các tài
liệu trong một cột XML, các kiểu dữ liệu cho các phần tử và các thuộc tính cụ thể
khơng có quyền ưu tiên (a-priori) đã biết. Vì vậy, mỗi chỉ mục XML đòi hỏi bạn
phải chỉ định một kiểu đích. Bạn sẽ thấy sau trong bài viết này lí do các kiểu lại
quan trọng. Các kiểu dữ liệu có sẵn cho các chỉ mục XML là:
VARCHAR(n): Cho các nút có các giá trị chuỗi có chiều dài tối đa n đã
biết.
VARCHAR HASHED: Cho các nút có các giá trị chuỗi có độ dài tùy ý.
Chỉ mục này có chứa các giá trị băm (hash) của chuỗi thực tế và có thể
được sử dụng chỉ cho các vị từ so sánh bằng, không cho vị từ so sánh xếp
hạng (range).
DOUBLE: Cho các nút có kiểu số bất kỳ.
DATE and TIMESTAMP: Cho các nút có các giá trị ngày tháng hoặc dấu
thời gian.
Chiều dài của một chỉ mục VARCHAR(n) là một sự ràng buộc cứng nhắc. Nếu
bạn chèn một tài liệu vào chỗ mà ở đó giá trị của một phần tử có chỉ mục hoặc
thuộc tính vượt quá độ dài tối đa n, việc chèn sẽ không thành công. Tương tự, câu
lệnh create index cho một chỉ mục VARCHAR(n) không chạy nếu bắt gặp một giá
trị lớn hơn n.
Theo mặc định, các kiểu dữ liệu cho các chỉ mục DOUBLE, DATE hoặc
TIMESTAMP không phải là một sự ràng buộc khó thực hiện. Ví dụ, chỉ mục idx1
trên thuộc tính định danh (ID) tác giả được định nghĩa là DOUBLE vì người ta
mong ID này có giá trị số. Nếu bạn chèn thêm một tài liệu vào chỗ mà ở đó một
ID của tác giả có giá trị "MN127", đây không phải số, tài liệu vẫn được chèn vào,
nhưng giá trị " MN127" không được thêm vào chỉ mục. Điều này là chính xác và
an tồn vì chỉ mục DOUBLE chỉ có thể đánh giá các vị từ số sẽ không bao giờ
khớp với giá trị "MN127". Như vậy, giá trị này có thể được loại bỏ khỏi chỉ mục
một cách an toàn.
Từ DB2 9.5 bạn có thể thêm câu tùy chọn REJECT INVALID VALUES vào định
nghĩa chỉ mục XML của bạn. Câu này buộc tuân theo các kiểu DOUBLE, DATE
hoặc TIMESTAMP của các chỉ mục như là một sự ràng buộc cứng nhắc. Nếu bạn
định nghĩa chỉ mục sau đây, một tài liệu mà ở đó một định danh (ID) tác giả có giá
trị "MN127" khơng thể được bổ sung và cần khơng có mặt trong cột XML, khi
bạn tạo chỉ mục này.
create index idx1 on books(bookinfo)
generate keys using xmlpattern
'/book/authors/author/@id'
as sql double REJECT INVALID VALUES;
Bạn có thể tìm thấy thêm các chi tiết về định nghĩa các chỉ mục XML trong "DB2
pureXML Cookbook". Trong thảo luận sau đây về cách sử dụng chỉ mục XML
chúng tôi cũng giả định rằng bạn đã quen thuộc với các khái niệm cơ bản về truy
vấn dữ liệu XML trong DB2. Để biết thêm thông tin, tham khảo các bài viết trước
đây, "Query DB2 XML Data with SQL" (Truy vấn dữ liệu XML DB2 với SQL)
(developerWorks, 03.2006) và "Query DB2 XML data with XQuery" (Truy vấn
dữ liệu XML DB2 với Xquery) (developerWorks, 04.2006) cho một sự khởi đầu,
cũng như "pureXML in DB2 9: Which way to query your XML data?" (pureXML
trong DB2 9: Dùng cách nào để truy vấn dữ liệu XML của bạn) (developerWorks,
06.2006) với nhiều ví dụ và chi tiết hơn.
Tính hợp lệ của chỉ mục XML đối với các câu lệnh XQuery và SQL/XML
Cũng như đối với các truy vấn quan hệ, các chỉ mục là điều quyết định đảm bảo
hiệu năng cao của các câu lệnh XQuery và SQL/XML của bạn. Khi ứng dụng của
bạn trình ra một truy vấn quan hệ hay truy vấn XML cho DB2, trình biên dịch truy
vấn so sánh các vị từ truy vấn với các định nghĩa chỉ mục hiện có và quyết định
xem có thể sử dụng bất kỳ các chỉ mục có sẵn nào để thực hiện truy vấn khơng.
Q trình này được gọi là "khớp chỉ mục" và tạo một tập (có thể rỗng) của các chỉ
mục hợp lệ đối với truy vấn cụ thể. Tập này là đầu vào cho trình tối ưu hóa
(optimizer) theo chi phí, nó quyết định có hay khơng sử dụng các chỉ mục hợp lệ
bất kỳ. Trong bài viết này, tập trung vào khớp chỉ mục chứ không phải lựa chọn
chỉ mục của trình tối ưu hóa. Khơng có nhiều thứ mà bạn có thể làm với các quyết
định của trình tối ưu hóa, trừ chạy "runstats" để đảm bảo trình tối ưu hóa với các
thống kê chính xác về dữ liệu của bạn. Tuy nhiên, có rất nhiều thứ mà bạn có thể
làm để đảm bảo khớp chỉ mục.
Khớp chỉ mục thường là dễ trong kiểu quan hệ. DB2 có thể sử dụng một chỉ mục
được định nghĩa trên một cột quan hệ duy nhất để trả lời bất kỳ vị từ bằng hay vị
từ xếp hạng trên cột này. Tuy nhiên, với các cột XML điều này phức tạp hơn.
Trong khi một chỉ mục trên một cột quan hệ chứa tất cả các giá trị từ cột đó, một
chỉ mục XML chỉ chứa các giá trị của các nút mà nó khớp cả hai mẫu XML và
kiểu dữ liệu XML trong định nghĩa chỉ mục. Vì thế, một chỉ mục XML có thể
được dùng để đánh giá một vị từ truy vấn XML chỉ khi chỉ mục này có kiểu dữ
liệu "đúng" và chứa ít nhất tất cả các nút XML nào thỏa mãn vị từ đó. Do đó, có
hai yêu cầu quan trọng để lựa chọn chỉ mục XML:
1. Định nghĩa chỉ mục XML là bằng hoặc ít hạn chế hơn vị từ truy vấn (bao
hàm - "containment").
2. Kiểu dữ liệu của các chỉ mục khớp với kiểu dữ liệu trong vị từ truy vấn.
Bài viết này giải thích cách thiết kế các chỉ mục XML và các truy vấn của bạn để
đảm bảo rằng các yêu cầu này được đáp ứng và cách tránh những cạm bẫy phổ
biến. Điều này bắt đầu với sự hiểu biết các kế hoạch thực hiện truy vấn của bạn.
Các công cụ giải thích hiện có trong DB2, chẳng hạn như Visual Explain (Giải
thích trực quan) và db2exfmt, có thể được sử dụng để xem các kế hoạch thực hiện
truy vấn XQuery và SQL/XML giống như khi chúng có thể làm cho SQL truyền
thống.
Đánh giá truy vấn XML: Các kế hoạch thực hiện và các toán tử mới
Để thực hiện các truy vấn XML, DB2 9 giới thiệu ba toán tử truy vấn bên trong
mới, được gọi là XSCAN, XISCAN và XANDOR. Cùng với các tốn tử truy vấn
hiện có (như TBSCAN, FETCH và SORT) các toán tử mới này cho phép DB2 tạo
ra các kế hoạch thực hiện cho SQL/XML và XQueries. Bây giờ hãy xem xét ba
toán tử mới và cách chúng làm việc cùng nhau với các chỉ mục XML trong một kế
hoạch thực hiện truy vấn.
XSCAN (XML Document Scan-Quét tài liệu XML)
DB2 sử dụng toán tử XSCAN để nghiên cứu các cây tài liệu XML và nếu cần, để
đánh giá các vị từ và trích ra các đoạn tài liệu và các giá trị. XSCAN không phải là
một "hoạt động quét bảng XML" nhưng nó có thể xuất hiện trong một kế hoạch
thực hiện sau khi việc quét bảng xử lý mỗi một tài liệu.
XISCAN (XML Index Scan-Quét chỉ mục XML)
Cũng giống như toán tử quét chỉ mục quan hệ hiện có cho các chỉ mục quan hệ
(XSCAN), toán tử XISCAN thực hiện các việc tra cứu hoặc quét trên các chỉ mục
XML. XISCAN lấy một vị từ giá trị làm đầu vào, chẳng hạn như một cặp đường
dẫn- giá trị như /book[price = 29] hoặc where $i/book/price = 29. Nó trả về một
tập các định danh (ID) hàng và các định danh nút. Các ID hàng chỉ rõ các hàng có
chứa các tài liệu đủ tiêu chuẩn và các ID nút chỉ rõ các nút đủ tiêu chuẩn trong các
tài liệu này.
XANDOR (XML Index AND'ing-AND chỉ mục XML)
Toán tử XANDOR đánh giá đồng thời hai hoặc nhiều vị từ bằng bằng cách điều
khiển nhiều XISCAN. Nó trả về các ID hàng của các tài liệu đáp ứng tất cả các vị
từ này.
Bây giờ hãy xem xét một truy vấn mẫu (trong ký hiệu XQuery và SQL/XML
tương đương) để hiểu kế hoạch thực hiện của nó khi khơng có chỉ mục, có một chỉ
mục và có nhiều chỉ mục:
-- XQuery:
xquery for $i in db2fn:xmlcolumn("BOOKS.BOOKINFO")
where $i/book/title = "Database systems" and
$i/book/price = 29
return $i/book/authors;
-- SQL/XML:
select XMLQUERY('$i/book/authors' passing bookinfo
as "i")
from books
where XMLEXISTS('$i/book[title = "Database systems"
and price = 29]'
passing bookinfo as "i");
-- Two Indexes:
create index idx1 on books(bookinfo) generate keys
using xmlpattern '/book/title' as sql varchar(50);
create index idx2 on books(bookinfo) generate keys
using xmlpattern '/book/price' as sql double;
Trong Hình 2, bạn thấy ba kế hoạch thực hiện khác nhau cho truy vấn này (đơn
giản hóa kết quả đầu ra từ db2exfmt). Tốt nhất là đọc các kế hoạch thực hiện từ
tốn tử bên trái thấp nhất trong cây đó, do luồng logic trong kế hoạch là từ dưới
đáy lên trên đỉnh và từ trái sang phải.
Kế hoạch tận cùng bên trái (a) được sử dụng nếu khơng có chỉ mục hợp lệ nào cho
các vị từ trong truy vấn này. Toán tử quét bảng (TBSCAN) đọc tất cả các hàng từ
bảng "BOOKS". Đối với mỗi hàng, toán tử kết nối lặp lồng nhau (NLJOIN)
chuyển một con trỏ tới tài liệu XML tương ứng với tốn tử XSCAN. Như vậy,
NLJOIN khơng hành động như phép kết nối kinh điển với hai chân đầu vào,
nhưng tạo điều kiện truy cập dữ liệu XML cho toán tử XSCAN. Toán tử XSCAN
duyệt từng tài liệu, đánh giá các vị từ và trích ra từ phần tử tác giả ("authors") nếu
các vị từ được thỏa mãn. Tốn tử RETURN hồn thành việc thực hiện truy vấn và
trả về kết quả truy vấn tới API.
Hình 2. Ba kế hoạch thực hiện (a) khơng có chỉ mục nào, (b) một chỉ mục, (c)
hai chỉ mục
Nếu bạn có một chỉ mục cho một trong hai vị từ, ví dụ như chỉ mục idx1 trên
/book/price, bạn sẽ thấy một kế hoạch thực hiện tương tự như kế hoạch (b) trong
Hình 2. XISCAN khảo sát kỹ chỉ mục với cặp đường dẫn-giá trị (/book/price, 29)
và trả về các ID hàng cho các tài liệu ở đó có giá là 29. Các ID hàng này được sắp
xếp để loại bỏ các hàng trùng lặp (nếu có) và tối ưu hóa các I/O kế tiếp vào bảng.
Toán tử quét ID hàng (RIDSCN) quét các ID hàng, kích hoạt hàng, và chuyển các
ID hàng đến toán tử FETCH. Đối với mỗi ID hàng, tốn tử FETCH đọc hàng
tương ứng từ bảng. Lợi ích của kế hoạch này là chỉ có một phần nhỏ trong số các
hàng trong bảng được lấy ra, có nghĩa là chỉ những hàng mà "giá" là 29. Cách làm
này rất lợi so với việc quét toàn bộ bảng để đọc mọi hàng. Đối với mỗi hàng được
lấy về, toán tử XSCAN xử lý tài liệu XML tương ứng. Nó đánh giá vị từ theo "tiêu
đề" ("title") và nếu vị từ thỏa mãn, trích ra phần tử "authors". Có thể có nhiều tài
liệu mà vị từ thứ hai khơng đúng và XSCAN vẫn có thể thực hiện rất nhiều cơng
việc để loại chúng ra. Vì thế, thậm chí bạn có thể thấy hiệu năng tốt hơn nếu vị từ
thứ hai cũng được dùng một chỉ mục.
Nếu bạn có các chỉ mục cho cả hai vị từ bạn có thể xem kế hoạch thực hiện (c)
trong Hình 2. Kế hoạch này sử dụng hai XISCAN, một cho mỗi vị từ và chỉ mục.
Toán tử XANDOR sử dụng các XISCAN để khảo sát luân phiên trong hai chỉ mục
để tìm các ID hàng của các tài liệu khớp với cả hai một cách hiệu quả. Tốn tử
FETCH sau đó chỉ lấy ra các hàng này, do đó giảm thiểu I/O đến bảng. Đối với
mỗi tài liệu, XSCAN trích ra phần tử "authors" kế tiếp nhau. Nếu các vị từ của bạn
bao gồm // hoặc * trong đường dẫn hoặc nếu bạn sử dụng các phép so sánh thứ
hạng (như là < và >), bạn sẽ thấy toán tử VÀ (AND) (IXAND) chỉ mục, thay cho
XANDOR. Điều hợp lý là, cả hai đều thực hiện cùng nhiệm vụ nhưng với các kiểu
các vị từ khác nhau và với việc tối ưu khác nhau.
Trình tối ưu hóa có thể quyết định khơng sử dụng một chỉ mục ngay cả khi nó cần
được dùng. Ví dụ, trình tối ưu hóa có thể chọn kế hoạch (b) hơn là kế hoạch (c)
nếu chỉ mục thứ hai không làm giảm đáng kể số hàng được lấy từ bảng, chẳng hạn
như nếu chi phí truy cập chỉ mục lớn hơn chi phí được lợi về I/O đến bảng. Tuy
vậy, bạn muốn chắc chắn rằng trình tối ưu hóa xem xét tất cả các chỉ mục hợp lệ
để sau đó chọn kế hoạch có chi phí thấp nhất và thời gian thực hiện ngắn nhất. Nói
cách khác, bạn muốn quan sát cả hai yêu cầu đối với tính hợp lệ của chỉ mục
XML:
Chỉ mục XML chứa ít nhất tất cả các nút XML thỏa mãn vị từ đó.
Kiểu dữ liệu trong vị từ truy vấn và định nghĩa chỉ mục đều tương thích.
Các ký tự đại diện trong các chỉ mục XML và các vị từ truy vấn
Các ký tự đại diện // và * có thể ảnh hưởng đến mối quan hệ bao hàm giữa một chỉ
mục và một vị từ truy vấn. Điều này là do các biểu thức đường dẫn như là
/book/price và //price khác nhau. Đường dẫn /book/price nhận biết tất cả các phần
tử price là phần tử con trực tiếp của phần tử "book" Tuy nhiên, đường dẫn //price
nhận biết các phần tử price bất kỳ ở đâu tại mức bất kỳ của một tài liệu XML.
Nhưng, /book/price nhận biết một tập con của các phần tử được //price chỉ rõ.
Người ta nói rằng //price "có chứa" /book/price nhưng khơng xoay trịn.
Bây giờ xem cách mà nó ảnh hưởng đến lựa chọn chỉ mục như thế nào. Hãy lấy
truy vấn sau đây làm một ví dụ. Nó chỉ ra bốn mức độ thay đổi của mệnh đề where
của nó trong Bảng 1.
XQUERY
for $i in db2-fn:xmlcolumn("BOOKS.BOOKINFO")
where $i/book/price = 29
return $i/book/authors
Hai cột đầu mút bên phải trong Bảng 1 trình bày hai định nghĩa chỉ mục thay thế
và các hàng trong bảng chỉ ra các hàng nào của các vị từ có thể (+) hoặc không thể
(-) được đánh giá bởi một trong số các chỉ mục. Bây giờ hãy bước qua các hàng
trong Bảng 1 để nghiên cứu lựa chọn chỉ mục cho từng vị từ.
Đối với vị từ đầu tiên, chỉ mục trên /book/price khơng hợp lệ vì nó chỉ chứa các
phần tử "giá" (price) là phần tử con trực tiếp của phần tử "book". Chỉ mục không
chứa phần tử "price" ở mức sâu hơn, mức này có thể tồn tại trong bảng và có các
sự khớp tiềm năng với đường dẫn vị từ $i//price. Vì vậy, nếu DB2 đã sử dụng chỉ
mục trên /book/price nó có thể trả về một kết quả không đầy đủ. Chỉ mục thứ hai,
trên //price, có hợp lệ vì nó có chứa tất cả các phần tử price ở mức tài liệu bất kỳ,
cần thiết cho vị từ đó.
Vị từ thứ ba sử dụng dấu sao (*) là một ký tự đại diện như là nó tìm kiếm bất kỳ
phần tử con nào dưới "book" có giá trị là 29. Khơng chỉ có các phần tử "price" có
thể đáp ứng vị từ này. Ví dụ, một tài liệu có giá trị 29 trong phần tử /book/title sẽ
là sự khớp hợp lệ. Tuy nhiên, các phần tử tiêu đề (title) không được bao gồm trong
một trong hai chỉ mục trong Bảng 1. Vì vậy, người ta khơng thể sử dụng cả hai chỉ
mục vì DB2 có thể trả về các kết quả không đầy đủ cho vị từ này.
Bảng 1. Tính hợp lệ về chỉ mục với các ký tự đại diện trong các chỉ mục và
các vị từ XML
Predicate/Index
...using xmlpattern
...using xmlpattern
Definition
'/book/price' as sql double;
'//price' as sql double;
-
+
+
+
3 where $i/book/* = 29
-
-
4 where $i/*/price = 29
-
+
#
1 where $i//price = 29
2
where $i/book/price =
29
Vị từ thứ tư $i/*/price = 29 tìm kiếm các phần tử price trong phần tử gốc bất kỳ,
khơng chỉ " book". Nếu có một tài liệu có một đường dẫn /journal/price, thì nó có
thể thỏa mãn vị từ $i/*/price = 29, nhưng nó sẽ khơng có trong chỉ mục trên
/book/price. Do đó, người ta khơng thể sử dụng chỉ mục này vì DB2 một lần nữa
sẽ có nguy cơ trả về một kết quả truy vấn không đầy đủ. Tuy nhiên, chỉ mục trên
//price chứa phần tử price bất kỳ, khơng phân biệt phần tử gốc.
Tóm lại, trình biên dịch truy vấn DB2 ln cần có khả năng chứng tỏ được chỉ
mục là như nhau hoặc ít hạn chế hơn vị từ, để nó chứa tất cả mọi thứ mà vị từ đang
tìm kiếm.
Hãy nhận thức rằng việc sử dụng các ký tự đại diện trong các định nghĩa chỉ mục
có thể vơ tình làm cho chỉ mục có thêm nhiều nút hơn cần thiết. Bất cứ ở đâu có
thể, nên sử dụng đường dẫn chính xác đến các phần tử hoặc các thuộc tính mong
muốn trong các định nghĩa chỉ mục và các truy vấn, mà không dùng các ký tự đại
diện. Có thể dùng các mẫu chỉ mục XML rất chung chung như là //* hoặc //text()
nhưng nên sử dụng cẩn thận. Một chỉ mục trên //* sẽ thậm chí đánh chỉ mục các
phần tử không phải lá, chúng thường không có lợi và có thể dễ dàng vượt quá sự
ràng buộc về độ dài của một chỉ mục Varchar(n).
Các vùng tên trong các chỉ mục và các vị từ truy vấn XML
Tính hợp lệ về chỉ mục XML địi hỏi sự chú ý của bạn nếu có bao gồm các vùng
tên. Trước hết, nếu các tài liệu XML trong bảng của bạn chứa các vùng tên, rồi
định nghĩa chỉ mục sẽ cần phải tính đến nó. Điều này lại dẫn đến bao hàm chỉ
mục/vị từ. Hãy lấy tài liệu XML và định nghĩa chỉ mục sau làm một ví dụ:
<bk:book xmlns:bk="">
<bk:title>Database Systems</bk:title>
<bk:price>29</bk:price>
</bk:book>
CREATE INDEX idx3 ON books(bookinfo)
GENERATE KEYS USING XMLPATTERN
'/book/price' AS SQL DOUBLE;
Chỉ mục idx3 này không chứa bất kỳ điểm vào chỉ mục nào cho tài liệu mẫu này
bởi vì nó được định nghĩa là một chỉ mục cho các phần tử /book/price với một
vùng tên rỗng. Tuy nhiên, bất kỳ trong số các định nghĩa chỉ mục sau đây có thể
được sử dụng để đánh chỉ mục phần tử price một cách phù hợp:
CREATE INDEX idx4 ON books(bookinfo)
GENERATE KEYS USING XMLPATTERN
'declare namespace bk="";
/bk:book/bk:price' AS SQL DOUBLE
CREATE INDEX idx5 ON books(bookinfo)
GENERATE KEYS USING XMLPATTERN
'declare default element namespace "";
/book/price' AS SQL DOUBLE
CREATE INDEX idx6 ON books(bookinfo)
GENERATE KEYS USING XMLPATTERN
'/*:book/*:price' AS SQL DOUBLE
Chỉ mục idx4 khai báo vùng tên và tiền tố tường minh để khớp với tài liệu. Chỉ
mục idx5 khai báo vùng tên như là một vùng tên mặc định và do đó khơng sử
dụng một tiền tố trong mẫu XML /book/price vì các vùng tên mặc định là ngầm
định. Chỉ mục idx6 chỉ đơn giản sử dụng các ký tự đại diện để khớp với vùng tên
bất kỳ. Cùng các tùy chọn đều được phép khi bạn tạo các vị từ trong các câu lệnh
XQuery hoặc SQL/XML:
Truy vấn 4:
-- XQuery:
XQUERY declare namespace
bk="";
for $b in db2fn:xmlcolumn("BOOKS.BOOKINFO")/bk:book
where $b/bk:price < 10
return $b
-- SQL/XML:
select bookinfo
from books
where XMLEXISTS('declare namespace
bk="";
$b/bk:book[bk:price < 10]'
passing bookinfo as "b")
Truy vấn 5:
-- XQuery:
XQUERY declare default element namespace
"";
for $b in db2fn:xmlcolumn("BOOKS.BOOKINFO")/book
where $b/price < 10
return $b
-- SQL/XML:
select bookinfo
from books
where XMLEXISTS('declare default element
namespace "";
$b/book[price < 10]'
passing bookinfo as "b")
Truy vấn 6:
-- XQuery:
XQUERY for $b in db2fn:xmlcolumn("BOOKS.BOOKINFO")/*:book
where $b/*:price < 10
return $b
-- SQL/XML:
select bookinfo
from books
where XMLEXISTS('$b/*:book[*:price < 10]'
passing bookinfo as "b")
Bảng 2 có một hàng cho mỗi một truy vấn trong ba truy vấn này và một cột cho
mỗi một trong các chỉ mục từ idx3 đến idx6 đã định nghĩa ở trên. Bạn có thể thực
hiện một số các quan sát quan trọng tại Bảng 2. Trước tiên, idx3 khơng có một
vùng tên sẽ không thể được sử dụng cho các truy vấn bất kỳ xem xét các vùng tên.
Tiếp theo, bạn thấy rằng các hàng cho truy vấn 4 và truy vấn 5 có các điểm vào
giống nhau và các cột cho các chỉ mục idx4 và idx5 cũng có các điểm vào chỉ mục
giống nhau. Điều này là do các định nghĩa vùng tên tường minh và các định nghĩa
vùng tên mặc định là cùng logic và chỉ là kí pháp khác nhau cho cùng một thứ.
Bạn có thể sử dụng chỉ mục nào cũng được mà không ảnh hưởng đến sự khớp chỉ
mục. Chỉ mục idx6 có các ký tự đại diện của vùng tên là hợp lệ cho tất cả các truy
vấn mẫu của bạn và thậm chí nó có thể được sử dụng cho một vị từ khơng có một
vùng tên, chẳng hạn như $b/price < 10. Chỉ mục idx6 cũng là chỉ mục duy nhất
khớp với vị từ trong truy vấn 6. Các chỉ mục idx4 và idx5 chứa các điểm vào chỉ
mục cho một vùng tên cụ thể nhưng không thể được sử dụng cho truy vấn 6 đang
tìm kiếm giá của sách trong vùng tên bất kỳ. Do đó, u cầu về tính bao hàm bị vi
phạm.
Bảng 2. Lựa chọn chỉ mục với các vùng tên trong các chỉ mục và các vị từ
XML
#
1
2
Định nghĩa truy
idx3 (khơng idx4 (vùng
vấn/chỉ mục
có vùng tên) tên rõ ràng)
Truy vấn 4 (vùng
tên rõ ràng)
Truy vấn 5 (vùng
tên mặc định)
idx5 (vùng
idx6 (các ký tự
tên mặc
đại diện của
định)
vùng tên)
-
+
+
+
-
+
+
+
-
-
-
+
Query 6 (các ký tự
3 đại diện của vùng
tên)
Kiểu dữ liệu trong các chỉ mục XML và các vị từ truy vấn
Ngồi các chỉ mục thích hợp hoặc tính bao hàm vị từ với các ký tự đại diện và các
vùng tên, yêu cầu thứ hai đối với tính hợp lệ về chỉ mục là các kiểu dữ liệu của các
vị từ và các chỉ mục cần phải khớp. Trong tất cả các ví dụ trước, phần tử
/book/price ln ln được đánh chỉ mục là DOUBLE. Nhưng, bạn có thể quyết
định đánh chỉ mục các giá sách như là VARCHAR, như chỉ ra trong Bảng 3. Tuy
nhiên, lưu ý rằng các vị từ giá trị cũng có một kiểu dữ liệu do kiểu giá trị bằng chữ
xác định. Một giá trị trong các dấu nháy kép luôn luôn là một chuỗi, nhưng một
một giá trị số khơng có dấu nháy kép được thể hiện như là một số. Như bạn thấy
trong Bảng 3, một vị từ chuỗi chỉ có thể được đánh giá bằng một chỉ mục XML
của kiểu VARCHAR, trong khi một vị từ số chỉ có thể được đánh giá bằng một chỉ
mục của kiểu DOUBLE.
Các kiểu dữ liệu của các chỉ mục quan hệ ln ln được kiểu cột có chỉ mục xác
định. Tuy nhiên, do DB2 không bắt buộc bạn phải kết hợp một lược đồ XML với
một cột XML, các kiểu dữ liệu cho các phần tử hoặc các thuộc tính khơng được
xác định trước. Vì vậy, mỗi chỉ mục XML địi hỏi một kiểu đích. Và kiểu là quan
trọng. Giả sử một phần tử giá (price) có giá trị 9. Một vị từ chuỗi "9" < "29" là sai,
trong khi một so sánh số 9 < 29 là đúng. Điều này nhấn mạnh rằng bạn nên sử
dụng các chỉ mục DOUBLE nếu bạn muốn các so sánh số chính xác theo ngữ
nghĩa. Phần tử "price"có khả năng lập chỉ mục tốt nhất là DOUBLE.
Bảng 3. Các kiểu dữ liệu trong các chỉ mục và các vị từ XML
#
1
2
Định nghĩa vị từ
...using xmlpattern
hoặc chỉ mục
'/book/price' as sql double;
where $i/book/price
< "29"
where $i/book/price
< 29
...using xmlpattern
'/book/price' as sql
varchar(10);
-
+
+
-
Sử dụng các chỉ mục cho các vị từ kết nối XML
Trong các ví dụ trước, bạn đã thấy các vị từ giá trị chứa các giá trị bằng chữ.
Những giá trị bằng chữ này xác định các kiểu dữ liệu so sánh. Sự xác định như vậy
thường không thể có cho các vị từ kết nối. Giả sử bạn có một bảng "các tác giả"
("authors") với các thơng tin chi tiết về tác giả theo một định dạng XML, bao gồm
các ID tác giả mà xuất hiện trong dữ liệu sách của bạn. Bạn muốn sử dụng một kết
nối để lấy ra dữ liệu chi tiết về tác giả chỉ dành cho các tác giả sách trong bảng
sách. Định nghĩa các chỉ mục theo các ID của tác giả có vẻ có ích:
create table books (bookinfo xml);
create table authors (authorinfo xml);
create index authorIdx1 on books(bookinfo) generate key
using
xmlpattern '/book/authors/author/@id' as sql double;
create index authorIdx2 on authors(authorinfo) generate
key using
xmlpattern '/author/@id' as sql double;
XQUERY
for $i in db2-fn:xmlcolumn("BOOKS.BOOKINFO")
for $j in db2fn:xmlcolumn("AUTHORS.AUTHORINFO")
where $i/book/authors/author/@id = $j/author/@id
return $j;
Truy vấn này lấy ra các thơng tin tác giả mong muốn, nhưng nó sẽ khơng sử dụng
chỉ mục để xử lý kết nối. Lưu ý rằng vị từ kết nối trên ID tác giả không chứa một
giá trị bằng chữ thường cho biết kiểu dữ liệu của so sánh. Do vậy, DB2 cần xem
xét khớp các ID tác giả của kiểu dữ liệu bất kỳ. Ví dụ, xem xét cuốn sách và dữ
liệu tác giả trong Bảng 4. Tác giả John Doe có một giá trị ID số (47), trong khi tác
giả Tom Noodle có một giá trị ID không phải là số (TN28). Cả hai đều có khớp
hợp lệ trong bảng khác. Vì vậy, cả hai cần có trong các kết quả của kết nối đó. Tuy
nhiên, nếu DB2 đã sử dụng các chỉ mục số authorIdx1 hoặc authorIdx2, nó sẽ
khơng tìm thấy ID của tác giả "TN28" và trả về một kết quả kết nối khơng đầy đủ.
Vì vậy, DB2 khơng thể sử dụng các chỉ mục đó và phải dùng đến việc quét bảng
để đảm bảo một kết quả truy vấn đúng.
Bảng 4. Cuốn sách thí dụ và dữ liệu tác giả
Cuốn sách
Tác giả
<author id="47">
<book>
<authors>
<author id="47">John
Doe</author>
</authors>
<title>Database
Systems</title>
29</price>
</book>
<name>John Doe</name>
<addr>
<street>555 Bailey
Av</street>
<city>San Jose</city>
<country>USA</country>
</addr>
4084511234</phone>
</author>
<book>
<authors>
<author id="TN28">Tom
Noodle</author>
<author id="TN28">
<name>Tom
Noodle</name>
<addr>
<street>213 Rigatoni
</authors>
<title>International
Road</street>
<city>Toronto</city>
Pasta</title>
19.95</price>
</book>
<country>Canada</country>
</addr>
4162050745</phone>
</author>
Tuy nhiên, trong nhiều trường hợp bạn có lẽ khơng có một sự pha trộn giữa các
giá trị số và không phải là số trong một phần tử hay thuộc tính đã cho của các tài
liệu của bạn. Nếu bạn biết rằng tất cả các ID tác giả là các số, bạn có thể chỉ thị
điều này trong truy vấn của bạn để cho phép DB2 sử dụng các chỉ mục DOUBLE.
Truy vấn sau đây tạo khuôn mẫu tường minh cho cả hai phía của vị từ kết nối theo
DOUBLE. Điều này chỉ yêu cầu một so sánh số và rõ ràng bỏ qua sự ăn khớp của
kết nối không phải số. Do vậy, DB2 có thể sử dụng một chỉ mục DOUBLE để xử
lý kết nối nhanh hơn.
XQUERY
for $i in db2-fn:xmlcolumn("BOOKS.BOOKINFO")
for $j in db2-fn:xmlcolumn