Toán tử logic HOẶC VÀ trong điều kiện và thứ tự các điều kiện trong WHERE


33

Hãy xem xét hai tuyên bố sau:

IF (CONDITION 1) OR (CONDITION 2)
...

IF (CONDITION 3) AND (CONDITION 4)
...

Nếu CONDITION 1TRUE, sẽ CONDITION 2được kiểm tra?
Nếu CONDITION 3FALSE, sẽ CONDITION 4được kiểm tra?

Điều gì về các điều kiện trên WHERE: công cụ SQL Server có tối ưu hóa tất cả các điều kiện trong một WHEREmệnh đề không? Các lập trình viên có nên đặt các điều kiện theo đúng thứ tự để chắc chắn rằng trình tối ưu hóa SQL Server giải quyết nó theo đúng cách?

THÊM:

Cảm ơn Jack đã liên kết, bất ngờ từ mã t-sql:

IF  1/0 = 1 OR 1 = 1
      SELECT 'True' AS result
ELSE
      SELECT 'False' AS result


IF  1/0 = 1 AND 1 = 0
      SELECT 'True' AS result
ELSE
      SELECT 'False' AS result

Trong trường hợp này, không có sự phân chia nào bằng 0 .

PHẦN KẾT LUẬN:

Nếu C ++ / C # / VB bị đoản mạch thì tại sao SQL Server không có nó?

Để thực sự trả lời điều này, chúng ta hãy xem làm thế nào cả hai làm việc với các điều kiện. C ++ / C # / VB đều có tính năng đoản mạch được xác định trong thông số kỹ thuật ngôn ngữ để tăng tốc độ thực thi mã. Tại sao phải đánh giá các điều kiện N HOẶC khi điều kiện đầu tiên đã đúng hoặc điều kiện M VÀ khi điều kiện đầu tiên đã sai.

Chúng tôi là nhà phát triển phải nhận thức được rằng SQL Server hoạt động khác nhau. Đây là một hệ thống dựa trên chi phí. Để có được kế hoạch thực hiện tối ưu cho truy vấn của chúng tôi, bộ xử lý truy vấn phải đánh giá mọi điều kiện và gán cho nó một chi phí. Các chi phí này sau đó được đánh giá toàn bộ để tạo thành một ngưỡng phải thấp hơn ngưỡng xác định mà SQL Server có cho một kế hoạch tốt. Nếu chi phí thấp hơn ngưỡng xác định, kế hoạch được sử dụng, nếu không, toàn bộ quá trình được lặp lại một lần nữa với sự pha trộn khác nhau của chi phí điều kiện. Chi phí ở đây là quét hoặc tìm kiếm hoặc tham gia hợp nhất hoặc tham gia băm, v.v ... Do đó, việc ngắn mạch như có sẵn trong C ++ / C # / VB đơn giản là không thể. Bạn có thể nghĩ rằng việc sử dụng chỉ mục trên một cột được tính là ngắn mạch nhưng thực tế không phải vậy. Nó chỉ buộc sử dụng chỉ số đó và rút ngắn danh sách các kế hoạch thực hiện có thể. Hệ thống vẫn dựa trên chi phí.

Là một nhà phát triển, bạn phải biết rằng SQL Server không thực hiện đoản mạch như được thực hiện trong các ngôn ngữ lập trình khác và bạn không thể làm gì để buộc nó phải làm.


Khối trích dẫn cuối cùng từ đâu? Bạn có thể thêm một tài liệu tham khảo?
Nick Chammas

Câu trả lời:


25

Không có gì đảm bảo trong SQL Server nếu hoặc theo thứ tự các câu lệnh sẽ được xử lý trong một WHEREmệnh đề. Biểu thức đơn cho phép câu lệnh ngắn mạch là CASE- WHEN. Sau đây là từ câu trả lời tôi đã đăng trên Stackoverflow:

Làm thế nào SQL Server ngắn mạch đánh giá điều kiện WHERE

Nó làm khi nó cảm thấy như vậy, nhưng không phải theo cách bạn nghĩ ngay lập tức.

Là một nhà phát triển, bạn phải biết rằng SQL Server không thực hiện đoản mạch như được thực hiện trong các ngôn ngữ lập trình khác và bạn không thể làm gì để buộc nó phải làm .

Để biết thêm chi tiết, hãy kiểm tra liên kết đầu tiên trong mục blog trên, điều này dẫn đến một blog khác:

SQL Server có ngắn mạch không?

Phán quyết cuối cùng? Chà, tôi chưa thực sự có một cái nào, nhưng có lẽ an toàn khi nói rằng lần duy nhất bạn có thể đảm bảo đoản mạch cụ thể là khi bạn thể hiện nhiều điều kiện KHI trong biểu thức CASE. Với các biểu thức boolean tiêu chuẩn, trình tối ưu hóa sẽ di chuyển mọi thứ xung quanh khi nó thấy phù hợp dựa trên các bảng, chỉ mục và dữ liệu bạn đang truy vấn.


2
Rõ ràng có một số trường hợp cạnh (hoặc một lỗi) mà thậm chí case không an toàn
Jack Douglas

1
Tôi cũng chứng minh một trường hợp khác (ha!), Nơi CASEnghỉ: dba.stackexchange.com/questions/12941/...
Aaron Bertrand


0

SQL là một ngôn ngữ lập trình khai báo . Không giống như, C ++, một ngôn ngữ lập trình bắt buộc .

Tức là bạn có thể nói với nó những gì bạn muốn trong kết quả cuối cùng, nhưng bạn không thể ra lệnh kết quả được thực thi như thế nào , tất cả tùy thuộc vào công cụ.

Cách thực sự duy nhất để đảm bảo "ngắn mạch" (hoặc bất kỳ luồng điều khiển nào khác ) bên trong WHERElà sử dụng các khung nhìn được lập chỉ mục, các bảng tạm thời và các cơ chế tương tự.

Tái bút Bạn cũng có thể sử dụng các gợi ý về kế hoạch thực hiện (để "gợi ý" cho công cụ cách thực hiện một truy vấn, chỉ mục nào sẽ sử dụng và CÁCH sử dụng chúng), chỉ cần nghĩ rằng tôi nên đề cập đến nó, trong khi chúng ta đang ở trong chủ đề này ...


-4

1) - HOẶC (bất kỳ một hoặc cả hai điều kiện sẽ là TRUE)

nếu điều kiện 1 là TRUE thì điều kiện 2 cũng sẽ được kiểm tra, nó có thể là TRUE hoặc FALSE

--AND (cả hai điều kiện phải ĐÚNG)

nếu điều kiện 1 là FALSE thì điều kiện 2 sẽ không được kiểm tra


"Nếu điều kiện 1 là FALSE thì điều kiện 2 sẽ không được kiểm tra" Điều này không đúng. Xem câu trả lời ở trên . SQL Server vẫn có thể đánh giá điều kiện 2 vì nó không thực hiện đánh giá ngắn mạch trong WHEREcác mệnh đề.
Nick Chammas

-4

Cách duy nhất để kiểm soát các điều kiện trong mệnh đề WHERE là sử dụng dấu ngoặc để nhóm chúng lại với nhau.

WHERE Col1 = 'Something' AND Col2 = 'Something' OR Col3 = 'Something' and Col4 = 'Something'

rất khác với

WHERE (Col1 = 'Something' AND Col2 = 'Something') OR (Col3 = 'Something' and Col4 = 'Something')

Chỉ tò mò thôi. Hai điều kiện này khác nhau như thế nào? Kết quả khác nhau, hiệu suất, kế hoạch thực hiện? Tôi nghĩ rằng họ sẽ tương đương.
ypercubeᵀᴹ

Với cái đầu tiên, bạn cần khớp Col1, Col4 và Col2 hoặc Col3. Trong dòng thứ hai để khớp với Col1 và Col2 hoặc bạn cần khớp Col3 và Col4 nhưng Col1 và Col4 sẽ không bao giờ cần phải được đánh giá cả hai.
mrdenny

1
Không, bạn sai rồi. ANDcó quyền ưu tiên cao hơn OR. Cả hai đều tương đương. Những gì bạn nói sẽ đúng cho WHERE Col1 = x AND (Col2 = x OR Col3 = x) AND Col4 = xtruy vấn. Xem thử nghiệm SQL-Fiddle
ypercubeᵀᴹ
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.