Chương 3 MỘT SỐ ĐỀ XUẤT KHÁC VỀ XỬ LÝ PHÉP NỐI TRONG CÁC HỆ CSDL
3.2 Một số phương án tiếp cận xử lý nối phân tán khác
3.2.4 Xử lý truy vấn chuỗi [7]
Như đã đề cập ở chương 2, trên thực tế có một lớp truy vấn quan trọng gọi là truy vấn chuỗi (chain query) và thuật toán đa thức xử lý bài toán này. Các truy vấn chuỗi thường có dạng:
n n A n n
A A
A
A R R R R
R1>< 1 2 >< 2 3 >< 3 ...>< −2 −1>< −1
Trong đó hai quan hệ không kề nhau (nonadjacent relations) thì không có thuộc tính nối chung, tức là Ai ≠ Aj với i≠ j. Để tránh sử dụng tích Descartes, thì vị trí của mỗi quan hệ được cố định, không thay đổi trong suốt quá trình tối ưu truy vấn chuỗi. Thí dụ trong tình huống phép nối có 3 quan hệ R1><A1 R2 ><A2 R3, thì các thứ tự nối có thể như sau: nối R1 với R2 trước sau đó mới thực hiện nối với R3:
2 3 1 2
1 )
(R ><A R ><A R , dấu ngoặc đơn biểu thị thứ tự nối, hoặc ta có thể thực hiện nối
R2 với R3 trước sau đó mới nối với R1: R1><A1 (R2><A2 R3). Bài toán đặt ra ở đây là cần xác định rằng với thứ tự nối nào thì truy vấn có chi phí nhỏ nhất.
Nếu như các quan hệ không phân mảnh , thì bằng cách sử dụng qui hoạch động chi phí (là tổng các chi phí truyền) của truy vấn chuỗi sẽ được tối ưu. Nếu các quan hệ được phân mảnh thì thời gian đáp ứng (là tổng thời gian xử lý cục bộ và thời gian truyền) vẫn có thể được tối thiểu với kết quả gần tối ưu.
Đầu tiên với truy vấn chuỗi cho trước, ta cần xác định chi phí nối nhỏ nhất giữa 2 quan hệ kề nhau Ri và Ri+1, gọi là costi,i+1, 1≤i≤n−1. Phép nối giữa 2 quan hệ có thể được thực hiện bằng nhiều phương pháp (nối sử dụng thông tin phụ thuộc vị trí, sử dụng qui hoạch băm, sử dụng phương pháp nhân bản- và-thay thế… ). Căn cứ vào phương pháp nối cũng như khía cạnh vật lý của dữ liệu (như lưu trữ, chỉ mục…) chi phí nhỏ nhất của phép nối giữa 2 quan hệ có thể thu dược thông qua việc chọn chiến lươc thực thi có chi phí tổng thể (ước lượng) là tối thiểu. Gọi Ri,i+1 là kết quả phép nối giữa Ri và Ri+1, ta có chi phí nhỏ nhất của thao tác nối 3 quan hệ Ri, Ri+1 và Ri+2 có thể là chi phí cho kết nối giữa Ri,i+1 và Ri+2 hoặc chi phí giữa Ri và Ri+1,i+2. Trước khi xét đến phép nối thứ 2, thì cần xác định costi,i+1 và
2 ,
costi+1i+ , và ta có chi phí nhỏ nhất để thực hiện nối 3 quan hệ là chi phí thực hiện nhỏ nhất cho phép nối 2 quan hệ cộng thêm các chi phí nối bổ sung nào đó. Quá trình này được lặp lại với các tập 4, 5, … quan hệ liền kề, cho đến khi thu được chi phí nhỏ nhất cho chuỗi nối n quan hệ. Quá trình trên được mô tả như sau:
Gọi costi,j, i< j là chi phí nhỏ nhất để thực hiện nối các quan hệ liền kề
j i
i R R
R , +1,..., , và Ri,j là kết quả của dãy nối đó. Nó có thể thu được bởi phép nối giữa Ri và Ri+1,j, hoặc giữa Ri,i+1 với Ri+2,j, hoặc …, hoặc Ri,j−1 với Rj. Khi chi phí để thu được Ri+1,j là costi+1,j, ta sẽ có chi phí để có được Ri,j là
j
ti1,
cos + + joinc(Ri,Ri+1,j), với joinc() là chi phí nhỏ nhất để nối hai quan hệ. Ta có:
)}
, ( cos
{cos min
costi,j = i≤k<j ti,k + tk+1,j + joinc Ri,k Rk+1,j (***)
Trong đó 0costk,k = , Rk,k =Rk. Mục tiêu của việc thực hiện tối ưu hóa truy vấn chuỗi là tìm phương án thực thi để có được R1,n với chi phí cost1,n nhỏ nhất. Giá trị của biểu thức (***) là chưa xác định khi truy vấn chưa thực thi, nên nó cần phải được dự đoán trong quá trình tối ưu hóa. Có nhiều yếu tố ảnh hưởng đến chi phí nối, một trong số đó là kích thước của quan hệ trung gian, và nó cũng cần phải được dự đoán. Một thuật toán từ dưới – lên được xây dựng dựa trên biểu thức (***), trong đó khi j-i = s, thì chi phí nhỏ nhất để nối tất cả (s+1) quan hệ được tính toán.
Tối ưu hóa – chuỗi – truy vấn Tính toán cost1,n
For j-i=1 to n-1 do
{tính costi,j dựa trên biểu thức (***);
Gọi K(i,j) là giá trị của k sao cho vế phải của biểu thức (***) là nhỏ- nhất, nghĩa là
costi,j =costi,K(i,j) +costK(i,j)+1,j + joinc(Ri,K(i,j),RK(i,j)+1,j); }
Đưa ra phương án thực thi. Phương án thực thi tối ưu có thể được sinh ra bởi việc tìm ngược (tracing back) các giá trị K(i,j) thích hợp. trước tiên với K(1,n) duy nhất
tương ứng với thao tác nối cuối cùng là R1,K(1,n) ><AK(i,j) RK(i,j)+1,n. Chi phí nhỏ nhất để có được R1,K(1,n) là cost1,K(1,n). Thêm nữa ta cũng có K(1,K(1,n)), mà với nó thao tác nối cuối cùng tương ứng cho ra quan hệ R1,K(1,n) có thể thu được. Tương tự như vậy thao tác nối cuối cùng tương ứng cho ra kết quả là quan hệ RK(1,n)+1,n cũng có thể thu được. Bằng việc lặp lại các thao tác này thứ tự thực hiện giữa n-1 nối được xác định.
t1,n
cos
1 ,
cost1n− cost2,n
…
3 ,
cost1 cost2,4 … costn−2,n
2 ,
cost1 cost2,3 cost3,4 … costn−1,n
1 ,
cost1 cost2,2 cost3,3 cost4,4 … costn,n
Hình 3. 16 Tính toán chi phí từ dưới – lên
Cần n-1 vòng lặp để tính toán cost1,n, trong đó vòng lặp đầu tiên tất cả các chi phí
j
ti,
cos được tính toán (với j-i=1), có n-1 phép toán như vậy. Trong vòng lặp thứ 2, tất cả các chi phí costi,j được tính toán (với j-i=2), có n-2 phép toán như vậy. Tổng quát, ở phép lặp thứ l tất cả các chi phí costi,j được tính toán (với j-i=l), có n-l phép toán như vậy. Như vậy tổng số các chi phí cần phải tính là:
∑=−11 = ( −1)( −2)= ( 2) 2
1
n
l l n n O n . Với mỗi i, j cho trước ta có thể có được costi,j thông qua việc tính toán và so sánh biểu thức j-i. Rõ ràng ta có n-1 là cận trên của j- i nên tổng số các phép toán cần thiết để tính toán cost1,n là O(n3). Giai đoạn hai của thuật toán chỉ cần O(n), Như vậy độ phức tạp thuật toán là O(n3). Hình 3.16 là một mô tả việc tính toán từ dưới lên.
Thí dụ 3.4:
Xét truy vấn chuỗi của 4 quan hệ: R1><A1 R2 ><A2 R3 ><A3 R4.
Khởi đầu chi phí nhỏ nhất của phép nối giữa hai quan hệ kề được ước lượng. Giả sử ta có: cost1,2 = joinc(R1,R2)=3, cost2,3 = joinc(R2,R3)=5và
6 ) , (
cost3,4 = joinc R3 R4 = . Rõ ràng K(1,2)=1, K(2,3)=2 và K(3,4)=3. Ta có chi phí nối nhỏ nhất của R1 ><A1 R2 ><A2 R3 là cost1,3 được tính bởi:
)}
, ( cos
), , (
min{cost1,2 + joinc R1,2 R3 t2,3+ joinc R1 R2,3
Giả sử rằng joinc(R1,2,R3)=4 và joinc(R1,R2,3)=1, thì ta sẽ có cost1,3= min{3+4, 5+1}=6, và K(1,3)=1. Chí phí tối thiểu để xử lý R2 ><A2 R3><A3 R4 là cost2,4 cũng được ước lượng, với joinc(R2,3,R4)=3 và joinc(R2,R3,4)=4, thì cost2,4= min{5+3, 6+4}=8 và K(2,4)=3. Cuối cùng chi phí để thực hiện nối cho 4 quan hệ là:
)}
, ( cos
), , ( cos
cos ), , ( min{cos
4 , 2 1 4
, 2
4 , 3 2 , 1 4
, 3 2
, 1 4
3 , 1 3
, 1
R R joinc t
R R joinc t
t R
R joinc t
+
+ +
+
Giả sử rằng joinc(R1,3,R4)=5, joinc(R1,2,R3,4)=4, joinc(R1,R2,4)=2 ta có cost1,4= min{6+5, 3+6+4, 8+2}=10 và K(1,4)=1. Bây giờ ta sẽ sử dụng các K(i,j) để xây dựng phương án thực thi với tổng chi phí là 10, với K(1,4)=1 ta biết được nối cuối cùng là R1><A1 R2,4, từ K(2,4)=3 ta biết được nối cuối cùng là để có R2,4 là
3 4 3 ,
2 R
R ><A , cuối cùng từ K(2,3)=2 ta biết R2,3 thu được từ R2 ><A2 R3. Từ đó ta
có phương án thực thi như sau:
) )
(( 2 2 3 3 4
1 1 R R R
R ><A ><A ><A .
Nhận xét:
1. Thuật toán trên sử dụng qui hoạch động, qua đó phương án tối ưu được xây dựng từ các lời giải tối ưu của các bài toán con (subproblems). Tuy nhiên qui hoạch động không phải lúc nào cũng có thể áp dụng được cho bài toán này. Thí dụ xét bài toán thực hiện nối của 3 quan hệ R1,R2 và R3. Giả sử rằng các mảnh của R1 và của R2 được định vị trên trạm S1 và S2 còn các mảnh của R3 được định vị trên S2 và S3 Giải pháp tối ưu để nối R1 và R2 có thể cần đến các mảnh của quan hệ kết quả trên trạm S1 và S2. Các phương
án tối ưu bộ phận (suboptimal solution) để thực hiện nối có thể có các mảnh trên các trạm S2 và S3, tuy nhiên quan hệ kết quả với các mảnh trên các trạm S2 và S3, lại có thể là lời giải tối ưu khi nối được thực hiện với R3. Do vậy phương án qui hoạch động không phải lúc nào cũng đưa lại lời giải tốt nhất.
Thuật toán dựa trên biểu thức (***) với giả thiết rằng các thao tác được thực hiện tuần tự. Nhưng trong nhiều trường hợp các thao tác có thể được thực hiện một cách song song. Ví dụ khi thực hiện nối cho quan hệ Ri với Ri+1 thì các quan hệ Ri+2, Ri+3, …, Rj cũng có thể được thực hiện nối. Do vậy cần áp dụng các heuristic cho thuật toán.
2. Thuật toán trên có thể sử dụng kết hợp các phương án thực hiện nối đã nêu trước đó (như thuật toán Phụ thuộc vị trí, Phân mảnh và nhân bản, phương pháp băm…).