2014-12-14 16 views
9

Tôi đang làm việc để tối ưu hóa một số thủ tục lưu trữ được sử dụng nhiều và chạy trên một kịch bản đưa ra câu hỏi mà tôi không thể tìm thấy bất kỳ câu trả lời nào: khi đánh giá TSQL trong một thủ tục được lưu trữ, SQL Server có ngắn mạch câu lệnh IF không?Câu lệnh IF ngắn mạch của SQL Server có phải không?

Ví dụ, giả sử một thủ tục lưu trữ có mã tương tự như:

IF @condition1 = 1 
OR EXISTS(SELECT 1 FROM table1 WHERE column1 = @value1) 
... 

Trong kịch bản này không SQL Server ngắn mạch đánh giá như vậy mà tuyên bố EXISTS không bao giờ được thực thi khi mệnh đề trước để đánh giá đúng?

Nếu nó không bao giờ hoặc đôi khi chỉ có, thì chúng tôi có một số viết lại trước chúng tôi.

+2

Không được bảo đảm. Kiểm tra kế hoạch thực hiện để xem nó có thực hiện trong trường hợp của bạn hay không. –

+0

Cảm ơn, 'không được bảo đảm' là những gì tôi đang tìm kiếm. Vấn đề là các thủ tục lưu trữ này được thực hiện trên hàng trăm DB khách hàng, vì vậy nếu kế hoạch thực hiện xác định điều này, chúng tôi không thể giả định nó sẽ được đánh giá giống nhau trên mọi hệ thống của khách hàng và cần viết lại. –

+1

Nếu bạn muốn đảm bảo gang thì tách ra thành nhiều câu lệnh 'if' sẽ làm điều đó. Khi [tôi nhìn vào điều này trước khi] (http://stackoverflow.com/a/5543985/73226) Tôi tìm thấy một số ví dụ về nó không ngắn mạch. Bạn cũng có thể xem xét sử dụng báo cáo trường hợp. –

Trả lời

4

Ngay cả khi nó có vẻ hoạt động, không nên dựa vào nó. Tuyên bố CASE là điều duy nhất mà tài liệu tuyên bố là ngắn mạch, nhưng thậm chí không phải là (hoặc ít nhất là không) luôn luôn trường hợp (hee hee). Đây là một trong số bug được may mắn là đã được khắc phục như SQL Server 2012 (xem nhận xét).

Ngoài các hang thỏ (một trong những thú vị, chắc chắn) của các liên kết trong ý kiến ​​từ các bình luận được đăng bởi @ Martin vào câu hỏi, bạn cũng nên kiểm tra bài viết này:

Understanding T-SQL Expression Short-Circuiting

và diễn đàn thảo luận liên quan đến bài viết đó.

3

Tin tốt là dường như ngắn mạch. Dưới đây là một ví dụ nhỏ:

DECLARE @condition1 bit = 1 

IF (@condition1 = 1) OR EXISTS(SELECT 1 FROM sys.objects) 
    PRINT 'True' 
ELSE 
    PRINT 'False' 

Khi @condition được thiết lập để 1, đây là kế hoạch thực hiện: 0 hàng quét từ sys.objects

execution plan 1

khi @condition được đặt thành 0, nó quét sys.objects bảng:

execution plan 2

Nhưng không có gì đảm bảo rằng đây sẽ là trường hợp mọi lúc.

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