2014-10-20 34 views
8

Một trong hai trường hợp sẽ hoạt động tốt hơn (gần đây tôi bị cáo buộc không cẩn thận với mã của mình vì tôi đã sử dụng sau này trong Oracle):Tồn tại/không tồn tại: 'chọn 1' và 'trường chọn'

Select * 
from Tab1 
Where (not) exists(Select 1 From Tab2 Where Tab1.id = Tab2.id) 


Select * 
from Tab1 
Where (not) exists(Select Field1 From Tab2 Where Tab1.id = Tab2.id) 

Hoặc cả hai đều giống nhau?

Vui lòng trả lời cả từ phối cảnh SQL Server cũng như phối cảnh của Oracle.

Tôi đã googled (chủ yếu từ phía máy chủ sql) và thấy rằng vẫn còn nhiều tranh cãi về điều này mặc dù ý kiến ​​/ giả thiết hiện tại của tôi là người tối ưu hóa trong cả RDMBS đủ trưởng thành để hiểu rằng tất cả những gì được yêu cầu từ truy vấn phụ là một giá trị Boolean.

+1

Không có sự khác biệt, cả hai đều giống nhau. Kiểm tra kế hoạch thực hiện cho cả hai truy vấn để xác minh. –

+0

Hãy xem câu trả lời này ..http: //stackoverflow.com/a/6140367/2975396 – TheGameiswar

Trả lời

8

Có, chúng giống nhau. exists kiểm tra xem có ít nhất một hàng trong truy vấn phụ hay không. Nếu có, nó sẽ đánh giá thành true. Các cột trong truy vấn phụ không quan trọng bằng bất kỳ cách nào.

Theo MSDN, exists:

Chỉ định một subquery để kiểm tra sự tồn tại của hàng.

Oracle:

Một EXISTS kiểm tra điều kiện cho sự tồn tại của các hàng trong một subquery.

Có lẽ MySQL documentation được thậm chí nhiều hơn giải thích:

Theo truyền thống, một EXISTS bắt đầu subquery với SELECT *, nhưng nó có thể bắt đầu với SELECT 5 hoặc CHỌN column1 hoặc bất cứ điều gì cả. MySQL bỏ qua danh sách SELECT trong truy vấn con như vậy, vì vậy nó không tạo ra sự khác biệt nào.

+0

Nó có tạo nên sự khác biệt cho Postgres không? – fatuhoku

+0

Tôi không biết. Tôi không có kinh nghiệm với Postegres. –

+1

PostgreSQL cũng giống nhau. Bạn cũng có thể chọn null như bất cứ thứ gì khác. –

4

Tôi biết điều này là cũ, nhưng muốn thêm vài điểm tôi quan sát thấy thời gian gần đây ..

Mặc dù tồn tại kiểm tra cho sự tồn tại duy nhất, khi chúng tôi viết "chọn *" tất cả, cột sẽ được mở rộng, khác với chi phí nhỏ này, không có sự khác biệt.

Nguồn:
http://www.sqlskills.com/blogs/conor/exists-subqueries-select-1-vs-select/

Cập nhật:
Điều tôi gọi dường như không valid.Even dù khi chúng ta viết, select 1, SQLServer sẽ mở rộng tất cả các cột ..

vui lòng tham khảo bên dưới liên kết để phân tích sâu và thống kê hiệu suất, khi sử dụng các cách tiếp cận khác nhau ..

Subquery using Exists 1 or Exists *

+0

Bài viết của Conor có thực sự sai. Ông đề nghị rằng 'SELECT *' sẽ mở rộng tất cả các siêu dữ liệu cột và 'SELECT 1' sẽ không. Tuy nhiên, cả hai thực tế đều làm như vậy. Bạn có thể thấy điều này bằng cách từ chối các điều khoản trên một cột và chạy 'SELECT 1 WHERE EXISTS (SELECT 1 FROM T);' có thể thất bại bất ngờ với 'Quyền SELECT bị từ chối trên cột 'Foo'' hoặc đơn giản là thời gian tác động của thêm nhiều cột hơn với cả hai hoặc tìm kiếm trong một trình gỡ lỗi http://stackoverflow.com/a/6140367/73226 –

+0

@MartinSmith: Cảm ơn rất nhiều, tôi đã đọc câu trả lời của bạn từ lâu, nhưng một số cách bỏ sót vài thứ. Cảm ơn bạn một lần nữa vì đã xóa bỏ huyền thoại – TheGameiswar

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