2010-06-21 29 views
6

Tôi tò mò về cách hiệu quả nhất để loại trừ truy vấn trên sql. Ví dụ. Có 2 bảng (tableA và tableB) có thể được nối trên 1 cột (col1). Tôi muốn hiển thị dữ liệu của tableA cho tất cả các hàng mà col1 không tồn tại trong tableB.SQL: So sánh hiệu suất để loại trừ (Tham gia vs Không in)

(Vì vậy, nói cách khác, TableB chứa một tập hợp con của col1 của tableA. Và tôi muốn hiển thị tableA không có dữ liệu tồn tại trong TableB)

Hãy nói rằng TableB có 100 dòng trong khi tableA là khổng lồ (hơn hơn 1 triệu hàng). Tôi biết 'Không ở trong (không tồn tại)' có thể được sử dụng nhưng có lẽ có những cách hiệu quả hơn (ít thời gian hơn) để làm điều đó.? Tôi không có thể với tham gia bên ngoài?

Đoạn mã và nhận xét được đánh giá cao.

+0

DBMS nào? SQL Server, MySQL, Oracle? Khả năng của trình tối ưu hóa truy vấn trong các khác biệt này. –

+0

Oracle. Tôi sẽ ngạc nhiên nếu có sự khác biệt về hiệu suất đáng kể so với các DBMS khác nhau. – someone

+0

Vâng, bạn sẽ ngạc nhiên. :) – Unreason

Trả lời

7

Phụ thuộc vào RDBMS. Đối với Microsoft SQL Server NOT EXISTS is preferred cho OUTER JOIN vì nó có thể sử dụng kết nối Chống bán hiệu quả hơn.

Đối với Oracle Minus is apparently preferred để NOT EXISTS (nơi thích hợp)

Bạn sẽ cần phải nhìn vào kế hoạch thực hiện và quyết định.

+0

Cảm ơn câu trả lời. DBMS mà tôi quan tâm là Oracle. Bạn có chắc rằng Minus có hiệu quả hơn truy vấn với câu trả lời của người tham gia hoặc của inflagranti không? – someone

+0

@ masa44 Không có gì cả. Mặc dù câu trả lời của inflagranti sử dụng EXCEPT mà * là * Minus trong Oracle. Đề nghị là để xem xét các kế hoạch thực hiện. –

+1

+1 để đề xuất điều tra kế hoạch thực hiện (trên dữ liệu thực với số liệu thống kê cập nhật). Ngoài ra câu hỏi là các chỉ số nào có mặt. – Unreason

1

Các câu hỏi đã được hỏi nhiều lần. Cách nhanh nhất thường là thực hiện việc này:

SELECT * FROM table1 
WHERE id in (SELECT id FROM table1 EXCEPT SELECT id FROM table2) 

Vì toàn bộ việc tham gia có thể được thực hiện trên các chỉ mục, khi sử dụng NOT IN thường không thể.

+0

Cảm ơn câu trả lời. Tôi không thể tìm thấy câu hỏi được hỏi trước đây. – someone

+0

Điều này ví dụ tôi nghĩ là tương tự: http://stackoverflow.com/questions/3074862/deleting-all-records-of-a-table-that-are-not-referenced-from-another-table/3074873#3074873 –

+0

Vâng, điều đó tương tự. Nhưng thật khó để tìm ra câu hỏi đó vì nó thiếu mô tả và thẻ chi tiết.Bạn biết điều đó bởi vì bạn đã trả lời rằng cách đây 2 ngày :) – someone

3

Tôi thích sử dụng

Select a.Col1 
From TableA a 
Left Join TableB b on a.Col1 = b.Col1 
Where b.Col1 Is Null 

Tôi tin rằng đây sẽ là nhanh hơn khi bạn đang sử dụng các hạn chế FK (cung cấp cho bạn có họ tất nhiên)

dữ liệu mẫu:

create table #a 
(
Col1 int 
) 
Create table #b 
(
col1 int 
) 

insert into #a 
Values (1) 
insert into #a 
Values (2) 
insert into #a 
Values (3) 
insert into #a 
Values (4) 

insert into #b 
Values (1) 
insert into #b 
Values (2) 


Select a.Col1 
From #a a 
Left Join #b b on a.col1 = b.Col1 
Where b.Col1 is null 
+0

Cảm ơn bạn đã trả lời nhưng giải pháp này không hiệu quả đối với tôi. Một lý do là Col1 không thể null (tableB chỉ có Col1). Vì vậy, giải pháp của bạn cho tôi không có kết quả. – someone

+0

@ Masa44 - Bạn có chắc chắn không? Nó làm việc cho tôi tốt. Tôi đã thêm một số dữ liệu thử nghiệm làm ví dụ. – codingbadger

+0

Tham gia trái thường không phải là cách nhanh nhất cho nhiều cơ sở dữ liệu. – HLGEM

-1

Không có câu trả lời đúng cho câu hỏi này. Mỗi RDBMS có trình tối ưu hóa truy vấn sẽ xác định kế hoạch thực thi tốt nhất dựa trên các chỉ mục có sẵn, thống kê bảng (số hàng, chỉ số chọn lọc), điều kiện tham gia, điều kiện truy vấn, ...

Khi bạn có truy vấn tương đối đơn giản như trong câu hỏi của mình , thường có một số cách bạn có thể nhận được kết quả trong SQL. Mọi RDBMS tự tôn trọng sẽ nhận ra ý định của bạn và sẽ tạo ra cùng một kế hoạch thực hiện, bất kể bạn sử dụng cú pháp nào (truy vấn con với toán tử IN hoặc EXISTS, truy vấn bằng JOIN, ...)

Vì vậy, giải pháp tốt nhất ở đây là viết đơn giản nhất truy vấn hoạt động và sau đó kiểm tra kế hoạch thực hiện.
Nếu giải pháp đó không được chấp nhận thì bạn nên cố gắng tìm truy vấn tốt hơn.

+0

Không, cơ sở dữ liệu sẽ không tạo ra cùng một kế hoạch cho các loại truy vấn khác nhau có cùng tập hợp kết quả. Nếu bạn nhìn nhà cung cấp bởi nhà cung cấp, bạn sẽ tìm ra cách nào hiệu quả nhất để thực hiện các loại truy vấn cụ thể. – HLGEM

+0

@HLGEM Bạn rõ ràng không bao giờ xem xét các kế hoạch thực hiện trong Oracle trong tình huống được mô tả trong câu hỏi. – zendar

+0

KHÔNG I l; ook tại các kế hoạch thực hiện trong máy chủ SQL, nơi có sự khác biệt rất lớn giữa các cách tiếp cận differnt như vậy với cùng một truy vấn. Tôi biết rằng tôi biết loại nào để thử đầu tiên. Viết truy vấn đơn giản nhất chỉ là lời khuyên xấu. ANd "Mọi RDBMS tự tôn trọng sẽ nhận ra ý định của bạn và sẽ tạo ra kế hoạch thực hiện tương tự, cho dù bạn sử dụng cú pháp nào" chỉ là sai. – HLGEM

Các vấn đề liên quan