Nested-Loop-Tham gia: Có bao nhiêu so sánh và bao nhiêu trang truy cập?


7

Giả sử bạn có hai mối quan hệ RS , trong đó R có 1000 bộ dữ liệu và 100 lần truy cập trang và S có 50 bộ dữ liệu và 25 lần truy cập trang.

Giả sử R là mối quan hệ bên ngoài, thì có bao nhiêu so sánh tuple và truy cập trang được thực hiện?

Và có bao nhiêu lượt truy cập trang nếu R là mối quan hệ bên trong?

for each tuple r in R do
   for each tuple s in S do
      if r and s satisfy the join condition
         then output the tuple (r,s)

Vì vậy, để tìm ra có bao nhiêu so sánh được thực hiện, tôi cần phải thực hiện 1000 * 50 = 50000 vì thuật toán đang thực hiện điều này "cho mỗi" tuple và chúng tôi có tổng cộng 1000 tuple cho R và 50 tuple cho S , do đó Tổng số 50000 so sánh.

Nhưng làm thế nào để biết truy cập trang bây giờ? Nếu R ở bên ngoài, chúng ta có (1000 tuple) * (25 lượt truy cập trang cho S ) + (100 lượt truy cập trang cho R ) = 25100 lượt truy cập trang?

Và nếu R ở bên trong, thì: 50 * 100 + 25 = 5025 lượt truy cập trang

Tôi không chắc liệu nó có đúng như vậy không .. hoặc làm thế nào để thực hiện chính xác? : /


1
"Trang" là gì? Bộ nhớ đệm có liên quan hay bạn cho rằng tất cả các trang đều có thể truy cập như nhau? Tại sao "trang truy cập một số liệu hữu ích? Đây có phải là" tham gia chéo "không, vì dường như không có liên quan đến việc giới hạn quyền truy cập vào bảng thứ hai trong NLJ.
Rick James

Câu trả lời:


11

Chúng tôi có thể buộc SQL Server thực hiện chính xác điều này và xem điều gì thực sự xảy ra.

R có 1000 tuple và 100 truy cập trang = 10 tuples / page = 806 byte / tuple.
S có 50 tuple và 25 truy cập trang = 2 tuples / page = 4030 byte / tuple.

Đây là các bảng:

drop table if exists dbo.R;
drop table if exists dbo.S;
go

create table dbo.R(n int, filler char(785)  not null default '');
create table dbo.S(n int, filler char(3990) not null default '');

Kích thước cột Filler đã được làm tròn xuống để cho phép hàng trên cao. Lưu ý rằng không có chỉ mục. Tôi có một bảng "số" mà tôi sẽ sử dụng để điền R và S:

insert dbo.R(n) select Number from dbo.Numbers where Number between 1 and 1000;
insert dbo.S(n) select Number from dbo.Numbers where Number between 1 and 50;

Chúng tôi có thể kiểm tra xem có bao nhiêu trang có liên quan:

set statistics io on;

select * from R
select * from S

Tab tin nhắn của SSMS hiển thị

Table 'R'. Scan count 1, logical reads 100, ...
Table 'S'. Scan count 1, logical reads 25, ...

Chúng tôi có đúng số lượng trang. Một chút trò đùa-pokery sẽ có được hành vi bạn muốn kiểm tra

select *
from dbo.R              -- R will be outer
inner loop join dbo.S
    on r.N = s.N
option
(
  force order,          -- dictate which table is outer and which inner
  NO_PERFORMANCE_SPOOL  -- stop the QO from doing something clever but distracting
);

select *
from dbo.S              -- S will be outer
inner loop join dbo.R
    on r.N = s.N
option (force order, NO_PERFORMANCE_SPOOL);

Cung cấp cái này trong tab tin nhắn (bảng bên trong được liệt kê trước bảng bên ngoài)

Table 'S'. Scan count 1, logical reads 25000, ...
Table 'R'. Scan count 1, logical reads 100, ...

Table 'R'. Scan count 1, logical reads 5000, ..
Table 'S'. Scan count 1, logical reads 25, ...

Trong SQL Server thực hiện truy vấn tiến hành hàng khôn ngoan. Đối với mỗi hàng trong bảng bên ngoài, (các) hàng tương ứng trong bảng bên trong sẽ được tham chiếu. Vì không có chỉ mục, tùy chọn duy nhất là đọc tất cả các hàng (tức là tất cả các trang) từ bảng bên trong mỗi lần. Đối với R-jo-S, chúng tôi có 1.000 hàng ngoài gấp 25 lần trang bên trong cung cấp 25.000 tài liệu tham khảo trang bên trong, tất nhiên, 100 tài liệu tham khảo trang bên ngoài. Đối với S-jo-R, có 50 hàng lần 100 trang, cung cấp 5.000 tham chiếu trang bên trong cộng với 25 tham chiếu trang bên ngoài.

Về mặt so sánh tuple bạn đúng - sẽ có so sánh O (R) xO (S) - 50.000. Điều này được hỗ trợ bằng cách nhìn vào kế hoạch truy vấn. Đối với cả hai truy vấn, "Số lượng hàng đã đọc" cho các tham chiếu bảng bên trong là 50.000.

Nếu có chỉ mục, trình tối ưu hóa truy vấn (QO) có các lựa chọn khác ngoài quét bảng. Tua lại có thể được sử dụng cho các phím ngoài trùng lặp. Không có trang nào có thể được đọc cho các khóa không khớp. Trong trường hợp cực đoan khi một ràng buộc nói rằng không thể có bất kỳ kết quả khớp nào, bảng bên trong thậm chí có thể không được tham chiếu.


Tôi nghĩ rằng có một lỗi đánh máy ở đây "so sánh - 50.000" & "tài liệu tham khảo là cả 50.000". Nó sẽ là 5000.
Rajesh Ranjan

1
@RajeshRanjan số lượng so sánh sẽ được tính (R) lần đếm (S) = 1.000 x 50 = 50.000. Chạy DDL & DML sau đó xem các thuộc tính kế hoạch truy vấn để tham chiếu bảng bên trong.
Michael Green

Oh! vâng, tôi đã bỏ qua "Số lượng hàng đã đọc". Bạn đúng.
Rajesh Ranjan

6

Sự thật có liên quan nhiều hơn những gì bạn nhận ra. Đúng là đầu vào bên ngoài của phép nối sẽ yêu cầu 1000 lần đọc logic nhưng chỉ khi khóa tham gia là duy nhất. Nếu không, trình tối ưu hóa có thể sắp xếp trước và tìm nạp nhiều hàng cùng lúc và khớp với tất cả chúng. Đối với vòng lặp bên trong, bạn đang giả sử quét toàn bộ mỗi lần lặp. Trình tối ưu hóa thường sẽ thích các vòng lặp lồng nhau nếu đầu vào bên trong được lập chỉ mục, trong trường hợp đó, số lần tìm nạp trang sẽ được xác định bởi số lượng thẻ của tập hợp đó.

5 xu của tôi - đừng lo lắng về các chi tiết thực hiện vật lý. Đầu tư tài nguyên của bạn vào việc hoàn thiện mô hình dữ liệu, lược đồ và mã. Hãy để động cơ lo lắng về các vòng lặp lồng nhau.

HTH

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.