2016-12-23 14 views
12

Tôi có hai bảng mỗi với khoảng 200.000 hàng. Tôi đã chạy truy vấn bên dưới và nó vẫn chưa hoàn thành sau khi chạy hơn một giờ. Điều gì có thể là giải thích cho điều này?Truy vấn SQL mất hơn một giờ để thực hiện cho 200k hàng

SELECT 
    dbo.[new].[colom1], 
    dbo.[new].[colom2], 
    dbo.[new].[colom3], 
    dbo.[new].[colom4], 
    dbo.[new].[Value] as 'nieuwe Value', 
    dbo.[old].[Value] as 'oude Value' 
FROM dbo.[new] 
JOIN dbo.[old] 
    ON dbo.[new].[colom1] = dbo.[old].[colom1] 
    and dbo.[new].[colom2] = dbo.[old].[colom2] 
    and dbo.[new].[colom3] = dbo.[old].[colom3] 
    and dbo.[new].[colom4] = dbo.[old].[colom4] 
where dbo.[new].[Value] <> dbo.[old].[Value] 

từ nhận xét;

Execution plan

Table structure

+2

Có thể bạn đang bị khóa. Hãy thử sử dụng với (nolock) để xác minh. Chỉ cần chắc chắn, vui lòng thêm kế hoạch thực hiện. –

+0

200.000 hàng tại một thời điểm quá nhiều và hiệu suất phải chậm. Thử sử dụng phân trang và hiển thị 10 - 20 dữ liệu trong một trang. Điều này có thể giúp một chút. –

+0

Tôi không thể thực hiện một kế hoạch thực hiện, bởi vì nó sẽ không thực hiện truy vấn, vì vậy tôi sẽ xóa một số hàng đầu tiên, trần với tôi –

Trả lời

7

Dường như đối với một bình đẳng tham gia trên một cột duy nhất, các hàng có giá trị NULL trong khóa kết nối đang được lọc ra, nhưng đây không phải là trường hợp tham gia trên nhiều cột.
Kết quả là độ phức tạp của hàm băm được thay đổi từ O (N) thành O (N^2).

============================================== ========================

Trong ngữ cảnh đó, tôi muốn giới thiệu một bài viết tuyệt vời được viết bởi Paul White về các sự cố tương tự - Hash Joins on Nullable Columns

============================================= =========================

Tôi đã tạo một mô phỏng nhỏ về trường hợp sử dụng này và tôi khuyến khích bạn kiểm tra các giải pháp của mình.

create table mytab1 (c1 int null,c2 int null) 
create table mytab2 (c1 int null,c2 int null) 

;with t(n) as (select 1 union all select n+1 from t where n < 10) 
insert into mytab1 select null,null from t t0,t t1,t t2,t t3,t t4 

insert into mytab2 select null,null from mytab1 

insert into mytab1 values (111,222); 
insert into mytab2 values (111,222); 

select * from mytab1 t1 join mytab2 t2 on t1.c1 = t2.c1 and t1.c2 = t2.c2 

Đối với truy vấn OP chúng ta nên loại bỏ hàng với giá trị NULL trong bất kỳ tham gia các cột quan trọng.

SELECT 
    dbo.[new].[colom1], 
    dbo.[new].[colom2], 
    dbo.[new].[colom3], 
    dbo.[new].[colom4], 
    dbo.[new].[Value] as 'nieuwe Value', 
    dbo.[old].[Value] as 'oude Value' 
FROM dbo.[new] 
JOIN dbo.[old] 
    ON dbo.[new].[colom1] = dbo.[old].[colom1] 
    and dbo.[new].[colom2] = dbo.[old].[colom2] 
    and dbo.[new].[colom3] = dbo.[old].[colom3] 
    and dbo.[new].[colom4] = dbo.[old].[colom4] 
where dbo.[new].[Value] <> dbo.[old].[Value] 
    and dbo.[new].[colom1] is not null 
    and dbo.[new].[colom2] is not null 
    and dbo.[new].[colom3] is not null 
    and dbo.[new].[colom4] is not null 
    and dbo.[old].[colom1] is not null 
    and dbo.[old].[colom2] is not null 
    and dbo.[old].[colom3] is not null 
    and dbo.[old].[colom4] is not null 
-1

Sử dụng TRỪ tham gia, bạn chỉ cần thực hiện các HASH lớn tham gia vào những giá trị đã thay đổi, vì vậy nhanh hơn nhiều:

/* 
create table [new] (colom1 int, colom2 int, colom3 int, colom4 int, [value] int) 
create table [old] (colom1 int, colom2 int, colom3 int, colom4 int, [value] int) 

insert old values (1,2,3,4,10) 
insert old values (1,2,3,5,10) 
insert old values (1,2,3,6,10) 
insert old values (1,2,3,7,10) 
insert old values (1,2,3,8,10) 
insert old values (1,2,3,9,10) 


insert new values (1,2,3,4,11) 
insert new values (1,2,3,5,10) 
insert new values (1,2,3,6,11) 
insert new values (1,2,3,7,10) 
insert new values (1,2,3,8,10) 
insert new values (1,2,3,9,11) 
*/ 

select n.colom1, n.colom2 , n.colom3, n.colom4, n.[value] as newvalue, o.value as oldvalue 
from new n 
inner join [old] o on n.colom1=o.colom1 and n.colom2=o.colom2 and n.colom3=o.colom3 and n.colom4=o.colom4 
inner join 
(
select colom1, colom2 , colom3, colom4, [value] from new 
except 
select colom1, colom2 , colom3, colom4, [value] from old 
) i on n.colom1=i.colom1 and n.colom2=i.colom2 and n.colom3=i.colom3 and n.colom4=i.colom4 
Các vấn đề liên quan