15 bài thực hành tốt nhất về hiệu năng pureXML trong DB2

DB2 9 giới thiệu sự hỗ trợ pureXML, có nghĩa là dữ liệu XML được lưu trữ và được truy vấn theo định dạng phân cấp vốn có của nó. Để truy vấn dữ liệu XML, DB2 cung cấp hai ngôn ngữ, SQL/XML và XQuery. Ngoài ra, DB2 9 có các khả năng lí tưởng về lập chỉ mục XML và hỗ trợ cho việc xác nhận tính hợp lệ của Lược đồ XML (XML Schema). Trong khi hầu hết các hướng dẫn thi hành hiện có cho DB2 cũng áp dụng cho dữ liệu XML, bài viết này cung cấp thêm các lời khuyên hiệu quả cho XML cụ thể. Bài viết này đã được cập nhật cho DB2 9.5. [26 tháng 5 năm 2009: mã hiệu chỉnh trong các liệt kê 12 và 13.--Biên tập.]

Matthias Nicola, Chuyên gia về hiệu năng CSDL, IBM Silicon Valley Laboratory

Matthias Nicola người lãnh đạo kỹ thuật về hiệu năng cơ sở dữ liệu XML tại Silicon Valley Lab của IBM. Công việc của ông tập trung vào tất cả các lĩnh vực về hiệu năng XML trong DB2, bao gồm XQuery, SQL/XML và tất cả các tính năng XML nguyên sơ trong DB2. Matthias Nicola cộng tác chặt chẽ với các đội phát triển XML DB2 cũng như với các khách hàng và các đối tác kinh doanh, là những người đang sử dụng XML, hỗ trợ họ trong việc thiết kế, triển khai thực hiện và tối ưu hóa các giải pháp XML. Trước khi gia nhập IBM, Matthias làm việc với hiệu năng kho dữ liệu cho Informix Software. Ông cũng đã có bốn năm làm việc trong các dự án nghiên cứu và các dự án công nghiệp trên cơ sở dữ liệu phân tán và nhân bản. Ông nhận bằng tiến sĩ khoa học máy tính vào năm 1999 ở Đại học Kỹ thuật Aachen, Đức.



26 05 2009 (Xuất bản lần đầu tiên vào ngày 23 10 2009)

Giới thiệu

Hỗ trợ pureXML trong DB2 9 cung cấp các khả năng hiệu quả và linh hoạt để quản lý dữ liệu XML của bạn. Hiệu năng là một sự ưu tiên cao cho nhiều ứng dụng XML; và các DBA, cũng như các nhà thiết kế ứng dụng, có thể chia sẻ khả năng của họ để đảm bảo hiệu năng tốt. Đầu tiên, có tất cả các hướng dẫn thực thi DB2 truyền thống cho các cấu hình cân bằng về CPU/bộ nhớ/đĩa, các vùng bảng và điều chỉnh vùng bộ đệm, khóa, ghi chép, các kế hoạch thực hiện truy vấn và v.v. Tất cả các chủ đề này được trình bày trong các bài viết DB2 trước đó (xem Tài nguyên) và vẫn có liên quan khi bạn quản lý dữ liệu XML trong DB2.

May mắn thay, một số trong các vấn đề này được các khả năng tự nhiên của DB2 xử lý như là quản lý lưu trữ tự động và quản lý bộ nhớ tự điều chỉnh. Chúng cung cấp các mức hiệu năng cao cho nhiều ứng dụng và đòi hỏi rất ít sự can thiệp thủ công. Nhưng các ứng dụng XML với các yêu cầu thực thi tích cực có thể được lợi ích từ các khía cạnh phụ về hiệu năng. Bài viết này tập trung vào các tình huống như vậy, đưa ra những lời khuyên và các hướng dẫn để đạt được hiệu năng tối đa của các ứng dụng XML có liên quan trong DB2 9.

Dưới đây là 15 lời khuyên hiệu năng XML (không theo thứ tự cụ thể) mà chúng tôi thảo luận và minh họa trong bài viết này. 15 lời khuyên này bao gồm nhiều lĩnh vực, nhưng kinh nghiệm cho thấy rằng các ứng dụng với các vấn đề hiệu năng thường chỉ cần áp dụng một hoặc hai trong số các lời khuyên này để đạt Lời khuyên được hiệu năng mong muốn.

Trong cuộc thảo luận về các lời khuyên hiệu năng này, chúng tôi giả định rằng bạn đã quen thuộc với các công việc thực hành hiệu năng và quản trị DB2 cơ bản cũng như với các khái niệm cơ bản về sự hỗ trợ pureXML của DB2. Ví dụ, bạn nên biết về các cột XML, các chỉ mục XML và làm thế nào để truy vấn dữ liệu XML với SQL/XML và XQuery. Tất cả những điều kiện cần trước này được trình bày trong bài viết được xuất bản trước đó trên developerWorks (xem Tài nguyên).


Các lời khuyên hiệu năng XML của DB2

Lời khuyên 1: Sáng suốt lựa chọn độ chi tiết của tài liệu XML của bạn

Khi bạn thiết kế ứng dụng XML và cấu trúc tài liệu XML của bạn, nói cụ thể, bạn có thể có một sự lựa chọn để xác định dữ liệu nghiệp vụ nào được giữ cùng nhau trong một tài liệu XML. Ví dụ, trong bảng bộ phận của chúng tôi dưới đây, chúng tôi sử dụng một tài liệu XML cho mỗi bộ phận (độ chi tiết trung bình). Đây là một sự lựa chọn có lý nếu một bộ phận có độ chi tiết nổi trội hơn mà ứng dụng của chúng tôi truy cập và xử lý dữ liệu tại đó. Theo cách khác, chúng tôi có thể có quyết định kết hợp nhiều chi nhánh bộ phận hoặc nhiều bộ phận vào một tài liệu XML duy nhất, ví dụ: tất cả những người thuộc về một đơn vị (độ chi tiết thô). Điều này, tuy nhiên, là sự tối ưu nhỏ nếu chúng ta thường xử lý chỉ một bộ phận vào một lúc.

Bảng 1. Tạo bảng dept( unitID char(8), deptdoc xml)
unitIDdeptdoc
WWPR
<dept deptID='PR27'>
   <employee id='901'>
      <name>Jim Qu</name>
      <phone>408 555 1212</phone>
   </employee>
   <employee id='902'>
      <name>Peter Pan</name>
      <office>216</office>
   </employee>
</dept>
WWPR
<dept deptID='V15'>
   <employee id='673'>
      <name>Matt Foreman</name>
      <phone>416 891 7301</phone>
      <office>216</office>
   </employee>
   <description>This dept supports sales world wide</description>
</dept>
S-USE...
......

Chúng tôi cũng có thể đã quyết định phải có một tài liệu XML cho mỗi nhân viên (độ chi tiết cao), với một thuộc tính "dept" cho mỗi nhân viên để cho biết nhân viên đó thuộc về bộ phận nào. Đây sẽ là một sự lựa chọn rất tốt nếu các nhân viên tự mình sử dụng các đối tượng nghiệp vụ quan tâm, mà các đối tượng này thường được các nhân viên khác trong cùng một bộ phận truy cập và xử lý một cách độc lập. Nhưng, nếu ứng dụng đó thường đòi hỏi cùng lúc tất cả các nhân viên trong một bộ phận, tốt hơn là để một tài liệu XML cho mỗi bộ phận.

Cụ thể là, việc xử lý theo bó nhiều đối tượng nghiệp vụ độc lập trong một tài liệu duy nhất là không nên. DB2 sử dụng các chỉ mục trên dữ liệu XML để lọc mức cho mỗi tài liệu. Vì vậy, độ chi tiết tài liệu XML của bạn càng tốt hơn, thì lợi thế tiềm năng của bạn càng cao do việc truy cập theo chỉ mục. Ngoài ra, nếu ứng dụng của bạn sử dụng một trình phân tích cú pháp DOM để tiêu thụ XML lấy ra từ DB2, các tài liệu nhỏ sẽ cho phép hiệu năng tốt hơn.

Liên quan đến thiết kế tài liệu XML, một câu hỏi thường gặp là khi nào sử dụng các thuộc tính so với các phần tử và lựa chọn đó ảnh hưởng đến hiệu năng ra sao. Đây là một câu hỏi về mô hình hóa dữ liệu hơn là một câu hỏi về hiệu năng. Như vậy, câu hỏi này cũng cũ như là SGML, tiền thân của XML và người ta đã tranh cãi sôi nổi mà không đạt được sự đồng thuận nào. Tuy nhiên, một thực tế quan trọng đi kèm là các phần tử XML linh hoạt hơn các thuộc tính bởi vì chúng có thể được lặp lại và lồng nhau. Ví dụ, trong các tài liệu của bộ phận chúng tôi, chúng tôi sử dụng một phần tử "phone" để cho phép chúng tôi có nhiều lần xuất hiện của "phone" nếu một nhân viên có nhiều số điện thoại. Nó cũng được mở rộng trong trường hợp sau này chúng tôi cần phải ngắt các số điện thoại vào trong các phân đoạn, nghĩa là phần tử "phone" có thể có các phần tử con cho mã nước, mã vùng, mã mở rộng, v.v. Nếu "phone" đã là một thuộc tính của các phần tử của nhân viên (employee), thì sau đó nó có thể tồn tại chỉ một lần cho mỗi nhân viên và chúng tôi cũng không thể thêm vào nó các phần tử con, thuộc tính phone có thể cản trở sự tiến hóa của lược đồ theo thời gian. Mặc dù bạn có thể mô hình hóa tất cả các dữ liệu của bạn mà dùng thuộc tính nào, chúng có thể là một lựa chọn rất trực quan cho các mục tin đã được biết trước là không bao giờ lặp lại (theo phần tử), cũng không có bất kỳ các trường con nào. Các thuộc tính làm cho XML ngắn hơn một chút vì chúng chỉ có một thẻ đơn, khác với các phần tử có một thẻ bắt đầu và một thẻ kết thúc. Trong DB2, các thuộc tính có thể được sử dụng trong các truy vấn, các vị từ và các định nghĩa chỉ mục, dễ như phần tử. Do các thuộc tính ít có khả năng mở rộng hơn so với các phần tử, nên DB2 có thể áp dụng việc tối ưu hóa lưu trữ và truy cập nào đó. Điều này cần được xem là lợi điểm về hiệu năng, hơn việc chỉ khích lệ chuyển đổi các thuộc tính thành các phần tử, đặc biệt khi các khía cạnh mô hình hóa dữ liệu thực sự gọi các phần tử.

Tóm lại, hãy chọn độ chi tiết của tài liệu XML của bạn đáp ứng độ chi tiết truy cập nổi trội đã dự liệu trước. Khi có nghi ngờ, tốt hơn là đi theo hướng độ chi tiết cao hơn và các tài liệu XML nhỏ hơn.

Lời khuyên 2: Sử dụng DMS và các trang lớn hơn để hiệu năng XML tốt hơn

DMS - Các vùng bảng quản lý cơ sở dữ liệu đảm bảo hiệu năng cao hơn so với SMS - các vùng bảng quản lý hệ điều hành. Điều này đúng với dữ liệu quan hệ và thậm chí cũng đúng cho việc truy cập đọc và viết XML. Trong DB2 9, theo mặc định các vùng bảng mới được tạo ra là DMS. Người ta cũng đề xuất sử dụng các vùng bảng DMS có vùng lưu trữ tự động sao cho các vùng chứa DMS phát triển khi cần thiết mà không cần có sự can thiệp thủ công. Nếu một tài liệu XML là quá lớn không vừa một trang duy nhất trong một vùng bảng, thì DB2 sẽ phân chia tài liệu thành nhiều vùng rồi sẽ lưu trữ trên nhiều trang. Điều này là trong suốt đối với ứng dụng của bạn và cho phép DB2 XML xử lý các tài liệu XML đến sự ràng buộc trong giới hạn 2GB cho mỗi tài liệu.

Nói chung, số các vùng (phân chia) cho mỗi tài liệu càng thấp thì hiệu năng càng tốt, đặc biệt đối với việc chèn và lấy ra tài liệu đầy đủ. Nếu một tài liệu không khít trên một trang, số lượng phân chia cho mỗi tài liệu phụ thuộc vào kích thước trang (4KB, 8KB, 16KB hoặc 32KB). Các kích thước trang của vùng bảng của bạn càng lớn thì số lượng phân chia tiềm tàng cho mỗi tài liệu càng thấp. Ví dụ, giả sử một tài liệu đã cho bắt đầu chia thành bốn mươi trang 4KB. Sau đó, lưu trữ cùng một tài liệu này chỉ trên hai mươi trang 8KB, hoặc mười trang16KB hoặc năm trang 32KB, tương ứng. Nếu các tài liệu XML này nhỏ hơn đáng kể so với kích thước trang đã chọn, thì sẽ không có vùng nào bị lãng phí do có thể lưu trữ nhiều tài liệu nhỏ trên một trang duy nhất.

Theo kinh nghiệm, chọn một kích thước trang cho dữ liệu XML không nhỏ hơn hai lần kích thước tài liệu dự kiến trung bình của bạn, với giả thuyết lớn nhất là 32KB. Nếu bạn sử dụng một kích thước trang đơn cho dữ liệu quan hệ và dữ liệu XML hoặc cho dữ liệu và các chỉ mục, một kích thước trang 32KB có thể mang lại lợi ích cho dữ liệu XML, nhưng hơi bất lợi cho việc truy cập dữ liệu và chỉ mục quan hệ. Trong trường hợp như vậy, các trang 16KB hoặc 8KB có thể là một lựa chọn tốt hơn để hoạt động tốt cho cả hai.

Lời khuyên 3: Khai thác các tùy chọn lưu trữ cho XML: nội tuyến, nén hoặc một vùng bảng riêng biệt

Hãy xem xét các bảng mẫu sau đây để thảo luận về các tùy chọn lưu trữ cho dữ liệu XML. Bảng này chứa dữ liệu quan hệ và dữ liệu XML:

Liệt kê 1. Bảng mẫu với dữ liệu XML và dữ liệu quan hệ
create table product(pid bigint, name varchar(20), brand varchar(35), 
                     category integer, price decimal, description XML);

Với định nghĩa bảng này, theo mặc định dữ liệu XML và dữ liệu quan hệ của bảng được lưu trữ mặc định trong cùng một vùng bảng. Điều này có nghĩa là chúng sử dụng cùng kích thước trang và được đệm trong cùng một vùng bộ đệm. Trong vùng bảng, dữ liệu quan hệ được lưu giữ trong đối tượng DAT, trong khi dữ liệu XML nằm trong đối tượng XDA. Điều này là do các tài liệu XML, như các LOB, có thể là quá lớn không khít trong một hàng đơn trên một trang dữ liệu của bảng. Sự bố trí mặc định này đảm bảo hiệu năng tốt cho hầu hết các kịch bản ứng dụng.

Nếu bạn đã thực hiện một sự phân tích hiệu năng và thấy rằng bạn cần phải có một kích thước trang lớn cho dữ liệu XML trừ một trang có kích thước nhỏ cho dữ liệu quan hệ hay các chỉ mục, bạn có thể sử dụng các vùng bảng riêng biệt để đạt được điều này. Khi bạn định nghĩa một bảng, bạn có thể hướng dữ liệu "dài" vào trong một vùng bảng riêng biệt có kích thước trang khác nhau. Dữ liệu dài bao gồm các dữ liệu LOB và dữ liệu XML.
Ví dụ sau định nghĩa hai vùng bộ đệm và hai vùng bảng, một thứ có các trang 4KB và 32KB. (Lưu ý rằng một vùng bảng luôn luôn đòi hỏi phải có một vùng bộ đệm có kích thước trang vừa khít). Bảng sản phẩm ("product") được gán cho vùng bảng "relData" có các trang 4KB. Trong vùng bảng đó lưu trữ tất cả các cột của nó, trừ cột mô tả ("description") XML, lưu trữ trên các trang 32KB trong vùng bảng "xmldata".

Liệt kê 2. Dữ liệu XML và dữ liệu quan hệ trong vùng bảng riêng biệt và các vùng bộ đệm
create bufferpool bp4k pagesize 4k;
create bufferpool bp32k pagesize 32k;

create tablespace relData
pagesize 4K
managed by automatic storage
bufferpool bp4k;

create tablespace xmlData
pagesize 32K
managed by automatic storage
bufferpool bp32k;

create table product(pid bigint, name varchar(20), brand varchar(35), 
                     category integer, price decimal, description XML) 
     in relData
     long in xmlData;

Các mặc định của vùng bảng trong DB2 9 khác nhau trong DB2 V8. Trừ khi xác định tường minh, các vùng bảng mới được tạo ra như DMS với các định danh (ID) hàng lớn. Điều này có nghĩa một vùng bảng với các trang 4KB có thể phát triển lên đến 2TB thay vì 64GB ở V8 và với các trang 32KB lên đến 16TB thay vì 512GB. Ngoài ra, loại bỏ giới hạn 255 hàng cho mỗi trang, cho phép lên đến 2.335 hàng trên các trang 32KB. Do đó, giới hạn hàng cho mỗi trang tự nó không còn là lý do để sử dụng các trang nhỏ cho dữ liệu quan hệ nữa.

DB2 9.5 cũng cho phép bạn lưu trữ dữ liệu XML "nội tuyến" và nén (compressed). Nếu một số hoặc tất cả các tài liệu XML của bạn là đủ nhỏ để khít với hàng tương ứng của chúng trên trang bảng cơ sở trong đối tượng DAT, chúng có thể được nội tuyến vào trong hàng quan hệ. Điều này đảm bảo truy cập trực tiếp hơn đến dữ liệu XML và tránh sự truy cập chuyển hướng đến đối tượng XDA. Nếu một số tài liệu trong cột XML vẫn còn quá lớn để được nội tuyến, chúng được lưu trữ "đường bao" trong đối tượng XDA như thường lệ. Việc nội tuyến có thể làm giảm đáng kể kích thước của chỉ mục các vùng do các tài liệu đã nội tuyến không yêu cầu bất kỳ điểm vào nào trên chỉ mục vùng. Chúng luôn luôn bao gồm một vùng đã nội tuyến, đơn. Các tài liệu được nội tuyến cũng có thể được nén bằng cách sử dụng phép nén hàng của DB2, như chỉ ra trong Liệt kê 3:

Liệt kê 3. Lưu trữ XML nén và nội tuyến
create table product(pid bigint, name varchar(20), brand varchar(35), 
                     category integer, price decimal, 
                     description XML inline length 3000) compress yes;

Trong ví dụ này, cột XML được định nghĩa với tùy chọn "inline length 3000" (độ dài nội tuyến 3000). Điều này có nghĩa là bất kỳ tài liệu nào có thể được lưu trữ trong 3.000 byte hoặc ít hơn sẽ được nội tuyến. Có liên quan với việc nội tuyến là kích thước của tài liệu sau khi phân tích cú pháp XML trong DB2, chứ không phải là kích thước của tài liệu XML văn bản trong hệ thống tệp của bạn. Độ dài nội tuyến phải nhỏ hơn kích thước trang trừ đi kích thước của các cột khác trong bảng đó. Dữ liệu XML đã nội tuyến luôn nằm trong vùng bảng giống như các cột quan hệ của bảng đó và không thể được lưu trữ trên trang khác hoặc trong một vùng bảng riêng biệt.

Kể từ khi bảng mẫu được định nghĩa với tùy chọn "compress yes" (có nén), dữ liệu quan hệ và các tài liệu XML nội tuyến bắt đầu được nén. Để nén dữ liệu XML đã nội tuyến xuống còn 70-85 phần trăm không phải là phổ biến. Có thể sử dụng các câu lệnh sau đây để kiểm tra tỉ số nén của bảng sản phẩm "product":

Liệt kê 4. Chức năng quản trị (Admin) để kiểm tra tỉ số nén
select tabname,pages_saved_percent,bytes_saved_percent 
from table(sysproc.admin_get_tab_compress_info('MYSCHEMA','PRODUCT','ESTIMATE')) as t

Nén dữ liệu XML có thể làm tăng hiệu năng rất lớn nếu hệ thống của bạn muốn ràng buộc I/O hơn là CPU bị ràng buộc. Lưu ý, tuy nhiên, việc nội tuyến làm tăng đáng kể kích thước hàng trên các trang dữ liệu của bạn. Điều này lần lượt giảm số lượng hàng cho mỗi trang. Các truy vấn mà chỉ truy cập vào các cột quan hệ của bảng bây giờ cần phải đọc một số lượng lớn các trang hơn số trang không nội tuyến. Điều này có thể dẫn đến có nhiều I/O hơn và hiệu năng cho các truy vấn này thấp hơn. Nếu các truy vấn của bạn thường luôn luôn có tác dụng đến cột XML đó, thì sau đó điều này không ảnh hưởng đến bạn.

Tóm lại, sử dụng khả năng phán đoán chung khi xem xét các vùng bảng riêng biệt cho dữ liệu XML. Càng ít vùng bộ đệm, vùng bảng và càng ít trang với kích thước khác biệt sẽ càng đơn giản khi thiết kế cơ sở dữ liệu vật lý để quản lý, duy trì và điều chỉnh. Tránh đưa vào các kích thước nhiều trang trừ khi bạn biết rằng nó thực sự cung cấp một lợi ích hiệu năng đáng giá. Sử dụng nội tuyến và nén để giảm tiêu thụ vùng lưu trữ và tăng hiệu năng I/O.

Lời khuyên 4: Đặt cấu hình DB2 để chèn nhanh số lượng lớn các dữ liệu XML như thế nào

DB2 9 hỗ trợ hai lựa chọn để di chuyển dữ liệu XML từ một hệ thống tệp vào trong một bảng DB2: chèn và nhập khẩu. Chèn và nhập khẩu có các đặc điểm tương tự như nhau từ hiệu năng và quan điểm vì tiện ích nhập khẩu thực sự thực hiện một loạt các hoạt động chèn.

Kể từ DB2 9.5, bạn cũng có thể sử dụng tiện ích LOAD DB2 để di chuyển dữ liệu XML vào một bảng. Các lợi thế chủ yếu của tiện ích LOAD với dữ liệu XML giống như với dữ liệu quan hệ, chẳng hạn như dữ liệu không lấy từ tệp log và việc song song hóa được tự động sử dụng để tăng hiệu năng. DB2 xác định một mức độ mặc định của song song dựa trên số CPU và các vùng chứa vùng bảng. Bạn cũng có thể thiết lập song song của CPU và I/O với các tham số CPU_PARALLELISM và DISK_PARALLELISM trong cú pháp của lệnh LOAD.

Cho dù ứng dụng của bạn thực hiện các hoạt động chèn số lượng lớn, có thể thông qua các luồng hoạt động chèn đồng thời hoặc nếu bạn sử dụng nhập khẩu hoặc nạp, các hướng dẫn thực thi sau đây áp dụng:

  • Là một điều kiện tiên quyết quan trọng, hãy chắc chắn sử dụng vùng bảng DMS với kích thước trang lớn (xem Lời khuyên 2).
  • Thậm chí nếu bạn chưa định nghĩa bất kỳ các chỉ mục trên bảng đích, cơ chế lưu trữ pureXML của DB2 sẽ duy trì trong suốt cái gọi là các vùng và các chỉ mục đường dẫn cho việc truy cập XML hiệu quả. Vì thế, cung cấp đủ vùng bộ đệm để hỗ trợ đọc chỉ mục.
  • Nếu bạn cần nhiều chỉ mục XML do người dùng định nghĩa trên bảng của bạn, tốt hơn là xác định chúng trước khi chèn số lượng lớn hơn là sau khi chèn mới tạo ra chúng. Trong hoạt động chèn, mỗi tài liệu XML sẽ được xử lý chỉ một lần để tạo các đầu vào chỉ mục đối với tất cả các chỉ mục XML. Tuy nhiên, nếu bạn đưa ra nhiều câu lệnh "create index", tất cả tài liệu trong cột XML sẽ bị chuyển nhiều lần.
  • Nếu bạn cần phải di chuyển một số lượng rất lớn các tệp XML nhỏ từ một hệ thống tệp vào trong một bảng DB2, có thể thực hiện hiệu quả là đặt chúng trong một hệ thống tệp dành riêng, mà không dùng chế độ truy cập nhanh tệp hệ thống. Vì mỗi tệp là chỉ đọc một lần, truy cập nhanh là không cần thiết. Trong AIX, người ta đã thấy có lợi khi gắn hệ thống tệp này với tùy chọn -o cio.

Hãy xem xét các hướng dẫn sau đây để chèn và nhập khẩu:

  • "ALTER TABLE <tablename> APPEND ON" cho phép gán thêm chế độ cho bảng đó. Dữ liệu mới được gán vào cuối của bảng thay vì tìm kiếm vùng trống trên các trang hiện có. Điều này đảm bảo tăng cường hiệu năng của hoạt động chèn số lượng lớn.
  • Tăng kích thước bộ đệm log (LOGBUFSZ) và kích thước của tệp log (LOGFILSIZ) cũng trợ giúp thực thi lệnh chèn. Điều này đặc biệt quan trọng đối với phép chèn XML do khối lượng dữ liệu cho mỗi hàng có xu hướng lớn hơn rất nhiều so với các dữ liệu quan hệ. Chúng tôi đề xuất sử dụng một thiết bị I/O nhanh cho tệp log.
  • Bạn có thể tránh việc ghi log nếu bạn sử dụng "ALTER TABLE <tablename> ACTIVATE NOT LOGGED INITIALLY" (NLI). Tuy nhiên, người ta đã cảnh báo rằng nếu có một câu lệnh sai, bảng sẽ được đánh dấu là không thể truy cập được và phải loại bỏ. Điều này thường cấm NLI với các phép chèn gia tăng số lượng lớn trong các hệ thống sản xuất, nhưng có thể có ích khi tạo dữ liệu khởi đầu cho một bảng trống. Coi chừng NLI ngăn cản các hoạt động chèn/nhập khẩu tương tranh vào trong một bảng đích và hoạt động song song có thể mang lại hiệu năng cao hơn NLI.
  • Nếu bạn sử dụng nhập khẩu, một giá trị nhỏ cho tham số COMMITCOUNT có xu hướng hại đến hiệu năng . Việc cam kết mỗi một 100 hàng hoặc nhiều hơn sẽ thực hiện tốt hơn so với cam kết từng hàng. Bạn cũng có thể bỏ qua tham số COMMITCOUNT và để cho DB2 cam kết mỗi khi thích hợp.
  • Để tận dụng tốt hơn nhiều CPU và đĩa, bạn có thể chạy đồng thời nhiều lệnh nhập khẩu. Hãy chắc chắn rằng, mỗi lệnh nhập khẩu chạy trong kết nối riêng của nó tới cơ sở dữ liệu và sử dụng mệnh đề "ALLOW WRITE ACCESS" để tránh việc khóa các bảng. Bạn không cần phải tách riêng tệp đầu vào (các tệp DEL) để chạy các lệnh nhập khẩu cùng nhau. Mỗi lệnh nhập khẩu có thể đọc một đoạn khác nhau của cùng tệp đầu vào do lệnh nhập khẩu cho phép bạn chỉ định "SKIPCOUNT m ROWCOUNT n" để đọc các hàng m+1 đến m+n từ tệp đầu vào.

Đối với các hướng dẫn thực thi lệnh chèn, xem bài viết "Các lời khuyên để cải thiện việc thực thi lệnh INSERT trong DB2 UDB" [xem Tài nguyên].

Tóm lại, lệnh chèn truyền thống và việc điều chỉnh hiệu năng ghi log là tốt cho việc chèn và nhập khẩu XML. Bạn có thể chạy các phiên nhập khẩu song song, nếu bạn thêm mệnh đề ALLOW WRITE ACCESS cho mỗi lệnh nhập khẩu. Trong DB2 9.5, sử dụng nạp vào thay cho nhập khẩu.

Lời khuyên 5: Sử dụng các yếu tố giám sát đột xuất để kiểm tra hiệu năng XML

Cho dù bạn đang kiểm tra lợi ích của các kích thước trang khác hoặc các lĩnh vực khác về hiệu năng XML, các cơ hội là bạn muốn sử dụng giám sát đột xuất DB2 như với dữ liệu quan hệ. Bạn sẽ thấy rằng DB2 9 cung cấp các yếu tố giám sát đột xuất cho vùng bộ đệm mới cho dữ liệu XML mà nó khít với các bộ đếm hiện có cho dữ liệu quan hệ và các chỉ mục. Do dữ liệu quan hệ và các chỉ mục được lưu trữ trong các đối tượng lưu trữ riêng biệt trong một vùng bảng, chúng đã tách riêng các bộ đếm đọc và viết. Lưu trữ pureXML trong DB2 9 giới thiệu một đối tượng lưu trữ mới cho dữ liệu XML, được gọi là XDA và nó cũng có bộ đếm vùng bộ đệm riêng của mình.

Ví dụ dưới đây là một đoạn trích từ một kết quả đầu ra của giám sát đột xuất. Bạn thấy các yếu tố từ màn hình chụp ứng với ba đối tượng lưu trữ khác nhau: dữ liệu, chỉ mục và XDA. Điều này cho phép bạn giám sát và phân tích hoạt động đệm và I/O đối với dữ liệu XML một cách riêng biệt khỏi dữ liệu quan hệ. Bất cứ hoạt động nào liên quan đến các chỉ mục XML đều có trong các bộ đếm chỉ số hiện tại. Diễn giải về các bộ đếm XDA mới giống như các bộ đếm quan hệ tương ứng của nó. Ví dụ, một tỷ lệ thấp của hoạt động đọc vật lý XDA với hoạt động đọc logic XDA cho biết tỷ lệ cụ thể của vùng bộ đệm cao đối với dữ liệu XML, như là mong muốn. Để biết thêm chi tiết về các yếu tố giám sát đột xuất của vùng bộ đệm, xem tài liệu DB2.

Liệt kê 5. Kết quả đầu ra của màn hình đối với dữ liệu, chỉ mục và các đối tượng lưu trữ XDA
Buffer pool data logical reads             = 221759
Buffer pool data physical reads            = 48580
Buffer pool temporary data logical reads   = 10730
Buffer pool temporary data physical reads  = 0
Buffer pool data writes                    = 6
Asynchronous pool data page reads          = 0
Asynchronous pool data page writes         = 6

Buffer pool index logical reads            = 8340915
Buffer pool index physical reads           = 54517
Buffer pool temporary index logical reads  = 0
Buffer pool temporary index physical reads = 0
Buffer pool index writes                   = 0
Asynchronous pool index page reads         = 0
Asynchronous pool index page writes        = 0

Buffer pool xda logical reads              = 2533633
Buffer pool xda physical reads             = 189056
Buffer pool temporary xda logical reads    = 374243
Buffer pool temporary xda physical reads   = 0
Buffer pool xda writes  
                   = 0
Asynchronous pool xda page reads           = 97728
Asynchronous pool xda page writes          = 0
Asynchronous data read requests            = 0
Asynchronous index read requests           = 0
Asynchronous xda read requests             = 83528

Tóm lại, các bộ đếm XDA mới trong đầu ra của màn hình chụp đột xuất phản ánh hoạt động XML. Chúng có ích để hiểu vùng bộ đệm, I/O và cách sử dụng vùng tạm thời (temp) của dữ liệu XML của bạn.

Lời khuyên 6: Hãy tăng cường xác nhận tính hợp lệ của lược đồ XML

Một lược đồ XML có thể định nghĩa cấu trúc, phần tử và các thuộc tính, các kiểu dữ liệu của chúng, các dải giá trị, v.v được phép trong một tập hợp các tài liệu XML. DB2 cho phép bạn (tùy chọn) xác nhận tính hợp lệ của các tài liệu XML với các lược đồ XML. Nếu bạn chọn xác nhận hợp lệ các tài liệu, bạn thường xác nhận tính hợp lệ tại thời điểm chèn. Điều này đáp ứng hai mục đích. Trước tiên, việc xác nhận hợp lệ đảm bảo rằng dữ liệu được chèn vào cơ sở dữ liệu phải tuân theo định nghĩa lược đồ, nghĩa là bạn ngăn chặn "dữ liệu rác" nhập vào bảng của bạn. Thứ hai, xác nhận hợp lệ lược đồ bổ sung thêm các chú thích về kiểu từ lược đồ này đến mỗi phần tử và thuộc tính XML và các kiểu này vẫn tiếp tục tồn tại trong vùng lưu trữ XML của DB2. Ví dụ, nếu một lược đồ XML định nghĩa rằng các ID của nhân viên trong bảng dept của chúng tôi (đã chỉ ra trong Lời khuyên 1) là các số nguyên và các tài liệu được xác nhận hợp lệ dựa vào lược đồ đó, sau đó DB2 nhớ trong mỗi tài liệu mà các ID của nhân viên có kiểu xs:integer. Bất kỳ cố gắng nào thực hiện một sự so sánh chuỗi trên một ID nhân viên sau đó sẽ bị hỏng với một lỗi kiểu trong thời gian thực hiện truy vấn.

Việc xác nhận tính hợp lệ của lược đồ XML là một hoạt động tùy chọn trong quá trình phân tích cú pháp XML. Các nghiên cứu hiệu năng đã chỉ ra rằng việc phân tích cú pháp XML nói chung cần nhiều CPU hơn đáng kể nếu việc xác nhận tính hợp lệ của lược đồ được kích hoạt [link]. Chi phí hoạt động này có thể thay đổi mạnh tùy thuộc vào cấu trúc và kích thước của tài liệu XML của bạn và đặc biệt là về kích thước và độ phức tạp của Lược đồ XML được sử dụng. Ví dụ, bạn có thể nhận thấy sự tiêu dùng CPU cao hơn 50% do việc xác nhận tính hợp lệ của lược đồ với các lược đồ phức tạp vừa phải. Trừ khi các hoạt động chèn vào XML của bạn là I/O bị ràng buộc rất nhiều, việc dùng tăng lên với CPU sẽ làm giảm thông lượng nhập vào.

Xác định xem ứng dụng của bạn cần kiểm tra kiểu nghiêm ngặt hơn đối với việc tuân thủ các truy vấn và lược đồ XML. Ví dụ, nếu bạn đang sử dụng một máy chủ ứng dụng thu nhận, xác nhận tính hợp lệ và xử lý các tài liệu XML trước khi chúng được lưu trữ trong cơ sở dữ liệu, sau đó các tài liệu đó có lẽ không cần phải được xác nhận lại tính hợp lệ trong DB2. Tại điểm đó bạn đã biết chúng hợp lệ rồi. Hoặc, có lẽ cơ sở dữ liệu đó nhận được các tài liệu XML từ một ứng dụng tin cậy, thậm chí là một ứng dụng mà bạn kiểm soát và bạn biết rằng dữ liệu XML là luôn luôn hợp lệ. Trong trường hợp đó, tránh xác nhận tính hợp lệ của lược đồ trước lợi ích về hiệu năng cao của phép nhập. Tuy nhiên, nếu cơ sở dữ liệu DB2 của bạn nhận được dữ liệu XML từ các nguồn không đáng tin cậy và bạn cần phải đảm bảo tuân thủ lược đồ ở mức DB2, thì bạn cần phải dành thêm một số chu kỳ CPU cho việc đó.

Tóm lại, để việc chèn đạt hiệu năng cao, tránh thực hiện xác nhận tính hợp lệ của lược đồ trong DB2 nếu nó không thực sự cần thiết.

Lời khuyên 7: Trong các biểu thức XPath, sử dụng các đường dẫn cụ thể đầy đủ càng nhiều càng tốt

Giả sử bạn có một bảng với một cột XML

create table customer(info XML);

để quản lý các tài liệu "customerinfo" có cấu trúc sau:

Liệt kê 6. Tài liệu XML mẫu
<customerinfo Cid="1004">
    <name>Matt Foreman</name>
    <addr country="Canada">
          <street>1596 Baseline</street>
          <city>Toronto</city>
          <state>Ontario</state>
          <pcode>M3Z-5H9</pcode>
    </addr>
    <phone type="work">905-555-4789</phone>
    <phone type="home">416-555-3376</phone>
</customerinfo>

Nếu bạn muốn lấy các số điện thoại của khách hàng hoặc thành phố mà họ sinh sống, có nhiều biểu thức đường dẫn có khả năng để nhận được dữ liệu đó, bất kể bạn có sử dụng XQuery hoặc SQL/XML. Cả hai /customerinfo/phone cũng như //phone sẽ giúp bạn có được những số điện thoại này. Tương tự như vậy, /customerinfo/addr/city cũng như /customerinfo/*/city trả về city. Để có hiệu năng tốt nhất, đường dẫn cụ thể đầy đủ sẽ được ưu tiên hơn so với cách sử dụng * hoặc // bởi vì nó cho phép DB2 chuyển hướng trực tiếp đến các phần tử mong muốn, bỏ qua các phần không liên quan của tài liệu.

Nói cách khác, nếu bạn biết được trong tài liệu đó phần tử mong muốn sẽ được đặt ở đâu, nó sẽ giúp cung cấp các thông tin đó dưới hình thức một đường cụ thể đầy đủ. Nếu bạn yêu cầu //phone thay cho /customerinfo/phone, bạn yêu cầu các phần tử phone bất kỳ ở đâu trong tài liệu. Điều này đòi hỏi DB2 chuyển hướng xuống vào nhánh cây con "addr" của tài liệu để tìm các phần tử phone ở bất kỳ mức tài liệu nào. Đây là hoạt động vượt quá có thể tránh được.

Lưu ý rằng * và // cũng có thể dẫn đến kết quả truy vấn không mong muốn hoặc bất ngờ. Ví dụ, nếu một số tài liệu "customerinfo" cũng có chứa thông tin "trợ lý" ("assistant"), giống như một bảng dưới đây. Đường dẫn //phone sẽ trả về các số điện thoại của khách hàng số điện thoại trợ lý, không phân biệt chúng. Từ các kết quả truy vấn bạn thậm chí sẽ không biết và xử lý nhầm lẫn số điện thoại trợ lý như là một số điện thoại của khách hàng.

Liệt kê 7. Các phần tử tên và số điện thoại ở nhiều mức trong tài liệu
<customerinfo Cid="1004">
    <name>Matt Foreman</name>
    <addr country="Canada">
          <street>1596 Baseline</street>
          <city>Toronto</city>
          <state>Ontario</state>
          <pcode>M3Z-5H9</pcode>
    </addr>
    <phone type="work">905-555-4789</phone>
    <phone type="home">416-555-3376</phone>
    <assistant>
          <name>Peter Smith</name>
          <phone type="home">416-555-3426</phone>
     </assistant>
</customerinfo>

Tóm lại, tránh dùng * và // trong các biểu thức đường dẫn của bạn và sử dụng các đường dẫn cụ thể đầy đủ thay vào đó, nếu có thể.

Lời khuyên 8: Định nghĩa các chỉ mục thiên về XML và tránh đánh chỉ mục tất cả mọi thứ

Giả sử các truy vấn của chúng tôi thường tìm kiếm các tài liệu "customerinfo" theo tên của khách hàng. Một chỉ mục trên phần tử tên khách hàng có thể cải thiện rất nhiều hiệu năng của các truy vấn như vậy. Hãy xem ví dụ sau:

Liệt kê 8. Các chỉ mục hỗ trợ tìm kiếm theo tên của khách hàng
create table customer(info XML);

create index custname1 on customer(info) 
generate key using xmlpattern '/customerinfo/name' as sql varchar(20);

create index custname2 on customer(info) 
generate key using xmlpattern '//name' as sql varchar(20);

select * from customer
where xmlexists('$i/customerinfo[name = "Matt Foreman"]' passing info as $i);

Cả hai chỉ mục được xác định ở trên có đủ điều kiện để đánh giá vị từ XMLEXISTS theo tên của khách hàng. Tuy nhiên, chỉ mục custname2 về cơ bản có thể lớn hơn chỉ mục custname1 bởi vì nó có chứa điểm vào chỉ mục không chỉ cho các tên khách hàng mà còn cho các tên trợ lý. Điều này là do mẫu XML //name phù hợp với các phần tử tên ở bất kỳ nơi nào trong tài liệu. Nhưng, nếu chúng ta không bao giờ tìm kiếm theo tên trợ lý thì chúng ta không cần lập chỉ mục chúng.

Đối với các hoạt động đọc, chỉ mục custname1 là nhỏ hơn và do đó có khả năng thực hiện tốt hơn. Với các phép chèn, cập nhật và xóa, chỉ mục custname1 phải gánh chịu chỉ phí bảo trì chỉ mục chỉ với tên khách hàng, trong khi chỉ mục custname2 yêu cầu bảo trì chỉ mục đối với tên khách hàng tên trợ lý. Bạn chắc chắn không muốn chi phí quá cao nếu bạn cần cực đại hiệu năng của phép chèn/cập nhật/xóa và không cần truy cập theo chỉ mục dựa trên các tên trợ lý.

Hơn nữa xem xét heavyIndex sau, nó "đánh chỉ mục tất cả mọi thứ". Nó bao gồm các điểm vào chỉ mục cho mọi nút văn bản, có nghĩa là mọi giá trị phần tử lá trong mọi tài liệu XML trong cột XML. Chỉ mục như vậy gây tốn kém về bảo trì trong các phép chèn/cập nhật/xóa, tiêu thụ rất nhiều vùng lưu trữ và thường là không khuyến khích. Ngoại lệ duy nhất có thể với các ứng dụng có hoạt động viết thấp và khối lượng công việc truy vấn không thể đoán trước, đến mức khó xác định các chỉ mục rất cụ thể.

create index heavyIndex on customer(info) 
generate key using xmlpattern '//text()' as sql varchar(20);

Tóm lại, càng chính xác càng tốt khi xác định các chỉ mục XML và tránh dùng * và // khi bạn có thể.

Lời khuyên 9: Đặt các vị từ lọc tài liệu trong XMLEXISTS thay cho XMLQUERY

Hãy xem xét các bảng và dữ liệu sau đây:

create table customer(info XML);
Bảng 2. Ba hàng dữ liệu trong bảng khách hàng
<customerinfo>
    <name>Matt Foreman</name>
    <phone>905-555-4789</phone>
</customerinfo>
<customerinfo>
    <name>Peter Jones</name>
    <phone>905-123-9065</phone>
</customerinfo>
<customerinfo>
    <name>Mary Poppins</name>
    <phone>905-890-0763</phone>
</customerinfo>

Căn cứ vào bảng này, giả sử rằng bạn muốn trả về các tên các khách hàng có số điện thoại "905-555-4789". Bạn có thể viết ngay câu truy vấn sau

select xmlquery('$i/customerinfo[phone = "905-555-4789"]/name' passing info as "i") 
from customer;

Tuy nhiên, truy vấn này không phải là những gì bạn muốn, vì nhiều lý do:

  1. Nó trả về tập kết quả sau mà nó có nhiều hàng như là những hàng có trong bảng. Điều này là do các câu lệnh SQL không có mệnh đề where và do đó không thể loại trừ bất kỳ hàng nào.
    <name>Matt Foreman</name>
    3 bản ghi được chọn.
  2. Đối với mỗi hàng trong bảng không khớp với vị từ, một hàng có chứa một chuỗi XML rỗng được trả về. Điều này là do biểu thức XQuery trong hàm XMLQUERY được áp dụng cho một hàng (tài liệu) tại một thời điểm và không bao giờ loại bỏ một hàng từ tập kết quả, chỉ thay đổi giá trị của nó. XQuery đó tạo ra giá trị hoặc là phần tử tên của khách hàng nếu vị từ đúng, hay ngược lại là một chuỗi rỗng. Các hàng rỗng này chính xác về ngữ nghĩa (theo chuẩn SQL/XML) và phải được trả về nếu truy vấn được viết theo cách nó có.
  3. Hiệu năng của truy vấn này sẽ không tốt. Đầu tiên, không thể sử dụng một chỉ mục có thể tồn tại trên /customerinfo/phone vì truy vấn này không được phép loại bỏ bất kỳ hàng nào. Thứ hai, trả về nhiều hàng rỗng làm cho truy vấn này chậm không cần thiết.

Để giải quyết các vấn đề hiệu năng nhận được kết quả đầu ra mong muốn, bạn nên sử dụng hàm XMLQUERY trong mệnh đề select chỉ để trích ra các tên khách hàng và thay đổi các điều kiện tìm kiếm, muốn loại bỏ các hàng, vào trong một vị từ XMLEXISTS trong mệnh đề where Điều này sẽ cho phép sử dụng chỉ mục, lọc hàng và tránh hoạt động quá với các hàng kết quả rỗng. Hãy viết truy vấn theo cách sau:

select xmlquery('$i/customerinfo/name' passing info as "i") 
from customer
where xmlexists('$i/customerinfo[phone = "905-555-4789"]' passing info as "i")
<name>Matt Foreman</name>

1 bản ghi được chọn.

Tóm lại, các vị từ trong hàm XMLQUERY chỉ được áp dụng trong mỗi giá trị XML, do đó chúng không bao giờ loại bỏ bất kỳ hàng nào. Các vị từ tài liệu và lọc hàng nên đi sâu vào hàm XMLEXISTS.

Lời khuyên 10: Sử dụng các dấu ngoặc vuông [] để tránh các vị từ Boolean trong hàm XMLEXISTS

Một lỗi phổ biến là viết các truy vấn trước đó mà không có dấu ngoặc vuông trong hàm XMLEXISTS:

select xmlquery('$i/customerinfo/name' passing info as "i") 
from customer
where xmlexists('$i/customerinfo/phone = "905-555-4789"' passing info as "i")

Điều này sẽ tạo ra kết quả sau:

<name>Matt Foreman</name>
<name>Peter Jones</name>
<name>Mary Poppins</name>

3 bản ghi được chọn.

Biểu thức trong vị từ XMLEXISTS được viết để cho XMLEXISTS luôn luôn đánh giá là đúng. Do đó, không có các hàng nào bị loại bỏ. Đó là vì, đối với một hàng cụ thể, vị từ XMLEXISTS đánh giá là sai chỉ khi biểu thức XQuery bên trong trả về chuỗi rỗng. Tuy nhiên, không có các dấu ngoặc vuông biểu thức XQuery là một biểu thức Boolean luôn luôn trả về một giá trị Boolean và không bao giờ là chuỗi rỗng. Lưu ý rằng XMLEXISTS thật sự kiểm tra sự tồn tại của một giá trị và đánh giá là đúng nếu một giá trị tồn tại, ngay cả khi giá trị đó xảy ra là giá trị Boolean "sai". Đây là hành vi đúng theo chuẩn SQL/XML, mặc dù nó có lẽ không phải điều bạn dự định thể hiện.

Tác động tiếp là không thể sử dụng chỉ mục cho phone vì không có hàng nào sẽ bị loại bỏ và bạn nhận được nhiều các hàng hơn bạn thực sự muốn có. Ngoài ra, hãy cẩn thận không tạo ra cùng một lỗi khi sử dụng hai hay nhiều vị từ, như trong truy vấn này:

Liệt kê 9. Sử dụng không đúng hai vị từ XMLEXISTS
select xmlquery('$i/customerinfo/name' passing info as "i") 
from customer
where xmlexists('$i/customerinfo[phone = "905-555-4789"] and 
		 $i/customerinfo[name = "Matt Foreman"]' 
      passing info as "i")

Truy vấn này sử dụng các dấu ngoặc vuông, vì vậy với nó có gì sai? Biểu thức XQuery vẫn là một biểu thức Boolean vì nó có dạng "exp1exp2". Dưới đây là cách viết truy vấn thích hợp để lọc các hàng và được phép sử dụng chỉ mục:

Liệt kê 10. Truy vấn đúng để lọc các hàng và được phép sử dụng chỉ mục
select xmlquery('$i/customerinfo/name' passing info as "i") 
from customer
where xmlexists('$i/customerinfo[phone = "905-555-4789" and name = "Matt Foreman"]' 
      passing info as "i")

Tóm lại, không sử dụng vị từ Boolean trong XMLEXISTS. Hãy đặt các vị từ trong ngoặc vuông, bao gồm bất kỳ "and" và "or".

Lời khuyên 11: Sử dụng RUNSTATS để thu thập các số liệu thống kê cho dữ liệu và chỉ mục XML

Tiện ích RUNSTATS đã được mở rộng để thu thập số liệu thống kê trên dữ liệu XML và các chỉ mục XML. Trình tối ưu hóa dựa vào chi phí của DB2 sử dụng các số liệu thống kê này để tạo ra các kế hoạch thực hiện hiệu quả cho các truy vấn XQuery và SQL/XML. Do đó, tiếp tục sử dụng RUNSTATS khi bạn muốn cho dữ liệu quan hệ. Nếu bảng của bạn có chứa dữ liệu quan hệ và dữ liệu XML và bạn muốn chỉ làm mới các số liệu thống kê quan hệ, bạn có thể thực hiện RUNSTATS với mệnh đề mới "EXCLUDING XML COLUMNS". Không có mệnh đề này, hành vị mặc định và hành vi ưa thích là luôn luôn thu thập số liệu thống kê cho dữ liệu quan hệ và dữ liệu XML.

Đối với dữ liệu quan hệ cũng như dữ liệu XML, bạn có thể chọn mẫu để giảm thời gian bằng cách thực hiện runstats. Trên một tập dữ liệu lớn, thống kê từ 10% dữ liệu (hoặc thậm chí ít hơn) thường là đại diện cho toàn bộ dữ liệu. Bất kể tỷ lệ phần trăm lấy mẫu mà bạn chọn, runstats cho phép bạn lấy mẫu các hàng (lấy mẫu Bernoulli) hoặc các trang (lấy mẫu hệ thống). Lấy mẫu mức hàng đọc tất cả các trang dữ liệu nhưng chỉ xem xét một tỷ lệ phần trăm của các hàng trên mỗi trang và do đó chỉ là một tập hợp con của các trang XDA tương ứng. Lấy mẫu mức trang giảm đáng kể I/O vì nó chỉ đọc có một tỷ lệ phần trăm các trang dữ liệu. Vì vậy, lấy mẫu trang có thể cải thiện một cách đáng kể hiệu năng nếu bảng của bạn có chứa không chỉ là XML, mà còn một số lượng khá lớn các dữ liệu quan hệ. Nhưng, lấy mẫu mức hàng có thể tạo ra các số liệu thống kê chính xác hơn nếu các giá trị dữ liệu quan hệ được gộp lại ở mức độ cao.

Dưới đây là một số ví dụ. Các lệnh runstats đầu tiên thu thập các thống kê có thể và chi tiết nhất cho bảng khách hàng và tất cả các chỉ mục của nó mà không cần lấy mẫu. Đây là lý tưởng nếu thời gian thực hiện cho phép. Lệnh thứ hai thu thập thống kê tương tự nhưng chỉ với 10% của các trang. Trong nhiều trường hợp, điều này sẽ cung cấp trình tối ưu hóa với gần các thống kê chính xác như là lệnh đầu tiên, nhưng sẽ trả về kết quả nhanh hơn nhiều. Lệnh thứ ba lấy mẫu 15% của tất cả các hàng, không thu thập số liệu thống kê phân phối và cũng áp dụng lấy mẫu cho các chỉ mục mà lệnh đầu tiên và lệnh thứ hai không làm.

Liệt kê 11. Sử dụng RUNSTATS để thu thập các số liệu thống kê
runstats on table myschema.customer 
with distribution on all columns and detailed indexes all;

runstats on table myschema.customer 
with distribution on all columns and detailed indexes all tablesample system (10);

runstats on table myschema.customer 
on all columns and sample detailed indexes all tablesample bernoulli (15);

Tóm lại, các DB2 tạo ra các kế hoạch thực hiện tốt hơn nếu các thống kê XML có sẵn. Sử dụng Runstats khi bạn muốn như thường lệ hoặc sử dụng runstats có lấy mẫu để giảm thiểu thời gian thực hiện của nó.

Lời khuyên 12: Làm thế nào để sử dụng các khung nhìn xuất bản SQL/XML để trưng ra dữ liệu quan hệ như XML

Các hàm xuất bản SQL/XML cho phép bạn biến đổi dữ liệu quan hệ thành định dạng XML. Nó có thể có ích để ẩn dấu các hàm xuất bản SQL/XML trong một định nghĩa khung nhìn, để cho các ứng dụng hoặc truy vấn khác có thể chọn đơn giản các tài liệu được kiến thiết theo XML từ khung nhìn thay vì làm việc với chính các hàm xuất bản.

Liệt kê 12. Các hàm xuất bản SQL/XML ẩn trong một khung nhìn
create table unit( unitID varchar(8), name varchar(20), manager varchar(20));

create view UnitView(unitID, name, unitdoc) as
   select unitID, name, 
       XMLDOCUMENT(
          XMLELEMENT(NAME "Unit",
          XMLELEMENT(NAME "ID", u.unitID),
          XMLELEMENT(NAME "UnitName", u.name),
          XMLELEMENT(NAME "Mgr", u.manager)
             )   )
   from unit u;

Lưu ý rằng chúng tôi bao gồm một số các cột quan hệ trong định nghĩa khung nhìn. Điều này không tạo ra bất kỳ sự dư thừa vật lý nào vì nó chỉ là một khung nhìn, chứ không phải một khung nhìn thực sự. Việc trích ra các cột quan hệ giúp truy vấn khung nhìn này có hiệu quả. Hãy nói rằng chúng ta cần phải tìm nạp một tài liệu XML cho một đơn vị cụ thể. Tất cả ba truy vấn sau đây có thể làm điều đó, nhưng truy vấn thứ ba có xu hướng thực hiện tốt hơn so với hai truy vấn đầu tiên.

Trong hai truy vấn đầu tiên, vị từ lọc được biểu diễn trên dạng kiến thiết của XML. Nhưng, không thể áp dụng các vị từ XML cho các cột quan hệ nằm bên dưới hoặc các chỉ mục của nó. Do đó, các truy vấn này cần khung nhìn để xây dựng XML cho tất cả các đơn vị và sau đó chọn ra một cho đơn vị "WWPR". Đây không phải là tối ưu.

Có thể thực hiện một cách tối ưu nhỏ:

Liệt kê 13. Các truy vấn thực hiện một cách tối ưu nhỏ
select unitdoc
from UnitView
where xmlexists('$i/Unit[ID = "WWPR"]' passing unitdoc as "i");

for $u in db2-fn:xmlcolumn('UNITVIEW.UNITDOC')/Unit
where $u/ID = "WWPR"
return $u;

Truy vấn thứ ba sử dụng một vị từ quan hệ để đảm bảo rằng chỉ có tài liệu XML cho "WWPR" được xây dựng, dẫn đến một thời gian chạy ngắn hơn, đặc biệt là trên một bộ dữ liệu lớn. Truy vấn này sẽ hoạt động tốt:

Liệt kê 14. Truy vấn thực hiện tốt
select unitdoc
from UnitView
where UnitID = "WWPR";

Tóm lại, bao gồm các cột quan hệ trong một khung nhìn xuất bản SQL/XML và khi truy vấn khung nhìn đó biểu diễn bất kỳ các vị từ nào trên các cột hơn là trên dạng kiến thiết từ XML.

Lời khuyên 13: Sử dụng các khung nhìn XMLTABLE để trưng ra dữ liệu XML trong định dạng quan hệ như thế nào

Cũng giống như để tạo ra một khung nhìn để trưng ra dữ liệu quan hệ theo định dạng XML có thể có ích lợi, bạn có thể muốn sử dụng một khung nhìn để trưng ra dữ liệu XML theo định dạng quan hệ. Cần có thận trọng tương tự như trong Lời khuyên 12, nhưng theo cách ngược lại. Hãy xem ví dụ sau, trong đó sử dụng hàm XMLTABLE SQL/XML để trả về các giá trị từ các tài liệu XML theo định dạng bảng:

Liệt kê 15. Giá trị được trả về từ các tài liệu XML theo định dạng bảng
create table customer(info XML);

create view myview(CustomerID, Name, Zip, Info) as 
SELECT T.*, info 
FROM customer, XMLTABLE ('$c/customerinfo' passing info as "c" 
   COLUMNS 
   "CID"     INTEGER      PATH './@Cid',
   "Name"    VARCHAR(30)  PATH './name',
   "Zip"     CHAR(12)     PATH './addr/pcode' ) as T;

Lưu ý rằng chúng tôi có các thông tin cột XML trong định nghĩa khung nhìn để giúp truy vấn khung nhìn này có hiệu quả. Hãy nói rằng bạn muốn lấy một danh sách bảng của các ID và tên khách hàng theo mã bưu điện cụ thể. Cả hai truy vấn sau đây có thể làm điều đó, nhưng truy vấn thứ hai có xu hướng thực hiện tốt hơn so với truy vấn đầu. Trong truy vấn đầu tiên, vị từ lọc được thể hiện trên cột "Zip" CHAR do hàm XMLTABLE tạo ra. Nhưng, các vị từ quan hệ không thể được áp dụng cho cột XML nằm bên dưới hoặc các chỉ mục của nó. Vì vậy, truy vấn này đòi hỏi khung nhìn để tạo ra các hàng cho tất cả khách hàng và sau đó chọn ra một cho mã bưu điện (zip) "95.141". Đây không phải là tối ưu. Truy vấn thứ hai sử dụng một vị từ XML để bảo đảm rằng chỉ có các hàng với "95.141" bắt đầu được tạo ra, dẫn đến thời gian chạy ngắn hơn, đặc biệt là trên một tập dữ liệu lớn.

Liệt kê 16. Truy vấn với một vị từ XML
-- may perform suboptimal:

select CustomerID, Name 
from myview
where Zip = "95141";


-- will perform well:

select CustomerID, Name
from myView
where xmlexists('$i/customerinfo[addr/pcode = "95141"]' passing info as "i");

Nếu bảng cơ sở mà trên đó khung nhìn được định nghĩa có chứa không chỉ một cột XML mà còn các cột quan hệ với các chỉ mục, bạn nên có các cột quan hệ đó trong định nghĩa khung nhìn. Nếu các truy vấn dựa vào khung nhìn có chứa các vị từ rất hạn chế trên các cột quan hệ, DB2 sử dụng các chỉ mục quan hệ để lọc các hàng đủ điều kiện về một số lượng nhỏ và sau đó áp dụng XMLTABLE và bất kỳ các vị từ còn lại cho kết quả tạm thời này trước khi trả về tập kết quả cuối cùng.

Tóm lại, hãy cẩn thận với các khung nhìn XMLTABLE, mà chúng trưng ra dữ liệu XML theo dạng quan hệ. Khi có thể, bao gồm các cột bổ sung trong định nghĩa khung nhìn sao cho các vị từ lọc có thể biểu diễn trên các cột đó thay vì các cột XMLTABLE.

Lời khuyên 14: Đối với các truy vấn ngắn hoặc các ứng dụng OLTP, sử dụng các câu lệnh SQL/XML với các dấu tham số

Các truy vấn cơ sở dữ liệu rất ngắn thường thực hiện nhanh tới mức thời gian biên dịch và tối ưu hóa chúng là một phần đáng kể so với của tổng số thời gian trả lời của chúng. Vì vậy, thật có ích để biên dịch ("chuẩn bị") chúng chỉ một lần và chỉ chuyển các giá trị bằng chữ của vị từ đối với mỗi lần thực hiện. Trong khi XQuery DB2 9 không hỗ trợ các tham số ngoài, các hàm XMLQUERY, XMLTABLE và XMLEXISTS của SQL/XML có hỗ trợ. Chúng cho phép bạn chuyển các dấu tham số SQL sang biến trong một biểu thức XQuery nhúng. Đây là khuyến cáo cho các ứng dụng có các truy vấn ngắn và lặp lại.

Liệt kê 17. Các giá trị bằng chữ của vị từ cố định (Hardcoded)
for $c in db2-fn:xmlcolumn('CUSTOMER.INFO')/customer
where $c/phone = "905-555-4789"
return $c;

select info 
from customer
where xmlexists('$i/customerinfo[phone = "905-555-4789"]' 
                passing info as "i")
Liệt kê 18. Với dấu tham số
select info 
from customer
where xmlexists('$i/customerinfo[phone = $p]' 
                passing info as "i", cast(? as varchar(12)) as "p")

Tóm lại, các truy vấn ngắn và các giao dịch OLTP nhanh hơn các câu lệnh được chuẩn bị với các dấu tham số. Đối với XML, điều này đòi hỏi SQL/XML chuyển các tham số dạng SQL sang các biểu thức XQuery.

Lời khuyên 15: Tránh chuyển đổi trang mã trong khi chèn và lấy ra XML

XML là khác với các kiểu dữ liệu trong DB2 bởi vì nó có thể được mã hóa trong và ngoài. Được mã hóa trong có nghĩa là mã hóa dữ liệu XML của bạn có thể suy diễn từ chính dữ liệu. Được mã hóa ngoài có nghĩa là mã hóa được suy diễn từ thông tin bên ngoài. Kiểu dữ liệu của các biến ứng dụng mà bạn sử dụng để trao đổi dữ liệu XML với DB2 xác định cách mã hóa được suy diễn. Nếu ứng dụng của bạn sử dụng các biến kiểu ký tự cho XML, thì nó được mã hóa ngoài, tức là trong các trang mã ứng dụng. Nếu bạn sử dụng các kiểu dữ liệu ứng dụng nhị phân, thì dữ liệu XML được coi là mã hóa trong. Được mã hóa trong có nghĩa là mã hóa được xác định bởi hoặc là một Unicode Byte-Order mark (BOM – Đánh dấu thứ tự byte Unicode) hoặc một khai báo mã hóa trong chính tài liệu XML, chẳng hạn như:

<?xml version="1.0" encoding="UTF-8" ?>

Từ một quan điểm thực thi của khung nhìn, mục đích là để tránh các phép biến đổi trang mã càng nhiều càng tốt vì chúng tiêu thụ chu kỳ CPU vượt trội. Dữ liệu XML mã hóa trong được ưa dùng hơn dữ liệu mã hóa bên ngoài, vì nó có thể ngăn ngừa phép biến đổi trang mã không cần thiết. Điều này có nghĩa rằng trong ứng dụng của bạn, bạn nên hướng về các kiểu dữ liệu mã nhị phân hơn các kiểu ký tự. Ví dụ, trong CLI khi bạn sử dụng SQLBindParameter() để ràng buộc các dấu tham số cho các bộ đệm dữ liệu đầu vào, bạn nên sử dụng bộ đệm dữ liệu SQL_C_BINARY hơn là SQL_C_CHAR, SQL_C_DBCHAR, hoặc SQL_C_WCHAR. Khi chèn dữ liệu XML trong các ứng dụng Java, đọc trong dữ liệu XML như một luồng nhị phân (setBinaryStream) là tốt hơn như một chuỗi (setString). Tương tự, nếu ứng dụng Java của bạn nhận được XML từ DB2 và ghi nó vào một tệp, phép biến đổi trang mã có thể xảy ra nếu các XML được viết như dữ liệu không phải nhị phân.

Khi bạn lấy dữ liệu XML từ DB2 đưa vào ứng dụng của bạn, nó là tuần tự. Tuần tự hóa là hoạt động ngược với phân tích cú pháp XML. Nó là quá trình biến đổi định dạng XML bên trong của DB2 (một thể hiện giống như cây, được duyệt) thành định dạng XML văn bản mà ứng dụng của bạn có thể hiểu được. Trong hầu hết trường hợp, tốt nhất là để cho DB2 thực hiện tuần tự hóa ngầm định. Điều này có nghĩa là các câu lệnh SQL/XML của bạn đơn giản chọn các giá trị kiểu-XML như trong ví dụ sau và DB2 thực hiện sự tuần tự hóa vào trong các biến ứng dụng của bạn càng hiệu quả càng tốt:

Liệt kê 19. Truy vấn với tuần tự hóa ngầm định
create table customer(info XML);

select info from customer where...;

select xmlquery('$i/customerinfo/name' passing info as "i") 
from customer
where...;

Nếu ứng dụng xử lý các tài liệu XML rất lớn, sử dụng các trình định vị (locator) LOB có thể có ích. Điều này đòi hỏi sự tuần tự hóa tường minh sang kiểu LOB, tốt nhất là BLOB, bởi vì sự tuần tự hóa rõ ràng sang kiểu ký tự như CLOB có thể đưa ra khía cạnh về mã và phép biến đổi trang mã không cần thiết. Sự tuần tự hóa tường minh sử dụng hàm XMLSERIALIZE:

select XMLSERIALIZE(info as BLOB(1M)) from customer where...;

Tóm lại, sử dụng các kiểu dữ liệu nhị phân trong ứng dụng của bạn để trao đổi XML với DB2 khi điều này tránh được phép biến đổi trang mã không cần thiết. Có ý thức về khía cạnh mã và khi có nghi ngờ, hãy theo các hướng dẫn chi tiết trong tài liệu hướng dẫn DB2 9.


Tóm tắt

Để đạt được hiệu năng XML tối đa trong DB2, một sự khởi đầu tốt là sử dụng các tính năng tự trị của DB2 như quản lý lưu trữ tự động và quản lý bộ nhớ tự điều chỉnh. Điều này đảm bảo hiệu năng bên ngoài gói, thích hợp cho nhiều ứng dụng. Nó cũng giải phóng thời gian DBA quý giá trong việc hiệu chỉnh hiệu năng mong muốn, khi cần thiết. Tất cả các sự hiểu biết về hiệu năng của DB2 vẫn được áp dụng cho XML và được trình bày trong nhiều bài viết của developerWorks được liệt kê dưới đây.

Trên hết, 15 lời khuyên trong bài viết này có thể giúp bạn bằng các khía cạnh chung chuyên về hiệu năng XML. Nếu bạn cần cải thiện hiệu năng của ứng dụng XML của bạn, bạn không cần phải áp dụng tất cả 15 lời khuyên mà chỉ cần áp dụng 1 hoặc 2 lời khuyên thực sự cần thiết trong tình hình của bạn. Ví dụ, giảm sự biến đổi trang mã không cần thiết sẽ không giúp đỡ được nếu hệ thống của bạn có I/O bị ràng buộc nhiều do một cấu hình vùng bảng không phù hợp. Tương tự như vậy, khi sử dụng các dấu tham số SQL/XML có thể không giúp gì cho hiệu năng truy vấn nếu bạn thực sự cần phải thực hiện runstats để kích hoạt các kế hoạch thực hiện truy vấn tốt hơn. Tóm lại, những lời khuyên trong bài này có thể giúp bạn tránh được các vấn đề hiệu năng, nhưng dừng các vấn đề hiệu năng đang theo dõi trước tiên cần nhận biết nguyên nhân căn bản và sự tắc nghẽn. Các công cụ chẩn đoán chuẩn trong DB2 như giải thích trực quan, db2exfmt và giám sát đột xuất có thể được sử dụng cho các việc kiểm tra hiệu năng XML giống như cho dữ liệu quan hệ.


Lời cảm ơn

Cảm ơn Cindy Saracco, Irina Kogan, Henrik Loeser, Nikolaj Richers và Marcus Roy về nhận xét của họ và giúp đỡ về bài viết này.

Tài nguyên

Học tập

Lấy sản phẩm và công nghệ

  • Truy cập vào The DB2 Snapshot Monitor để tìm hiểu những điều mới nhất về công cụ này và nhận được sản phẩm.
  • Tải về một phiên bản dùng thử miễn phí DB2 Enterprise 9.
  • Bây giờ bạn có thể sử dụng DB2 miễn phí. Hãy tải về bản DB2 Express-C, một phiên bản miễn phí của DB2 Express Edition cho cộng đồng, có cung cấp các tính năng dữ liệu cốt lõi như DB2 Express Edtion và cung cấp một cơ sở vững chắc để xây dựng và triển khai các ứng dụng.
  • Tải về DB2 Developer Workbench với một môi trường phát triển tích hợp cho DB2.

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Khi bạn đăng ký với trang developerWorks lần đầu tiên, một tiểu sử của của bạn được tạo ra. Chọn các thông tin về tiểu sử của bạn (tên, nước/vùng, và nơi làm việc) đã được hiện lên màn hình, thông tin này sẽ được hiện kèm với nội dung mà bạn đăng tải. Bạn có thể cập nhật thông tin này bất kỳ lúc nào.

Thông tin gửi đi được đảm bảo an toàn.

Chọn tên hiển thị của bạn



Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 ký tự)

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Thông tin gửi đi được đảm bảo an toàn.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Information Management, Nguồn mở
ArticleID=438455
ArticleTitle=15 bài thực hành tốt nhất về hiệu năng pureXML trong DB2
publish-date=05262009