2011-09-19 33 views
11

Mã phân tích quy tắc SR0007 cho Visual dự án cơ sở dữ liệu Studio 2010 khẳng định rằng:Có bao gồm các cột có thể vô hiệu trong ISNULL gây ra quét bảng không?

Bạn rõ ràng nên chỉ ra làm thế nào để xử lý các giá trị NULL trong các biểu thức so sánh bằng cách gói mỗi cột có thể chứa một giá trị NULL trong một chức năng ISNULL.

Tuy nhiên mã phân tích quy tắc SR0006 bị vi phạm khi:

Là một phần của một sự so sánh, một biểu thức có chứa một tham chiếu cột ... Mã của bạn có thể gây ra một bảng quét nếu nó so sánh một biểu thức có chứa một tham chiếu cột.

Điều này cũng áp dụng cho ISNULL hay ISNULL không bao giờ dẫn đến quét bảng?

Trả lời

17

Có nó gây ra việc quét bảng. (mặc dù dường như được tối ưu hóa nếu cột không thực sự có thể vô hiệu hóa)

Quy tắc SR0007 là lời khuyên cực kỳ kém vì nó hiển thị biến vị ngữ không thể dùng được và có nghĩa là bất kỳ chỉ mục nào trên cột sẽ vô dụng. Ngay cả khi không có chỉ số trên cột, nó vẫn có thể làm cho ước tính thẻ không chính xác ảnh hưởng đến các phần khác của kế hoạch.

Việc phân loại nó trong danh mục Microsoft.Performance khá thú vị vì dường như nó được viết bởi một người không hiểu về hiệu suất truy vấn.

Nó tuyên bố lý do là

Nếu mã của bạn so sánh hai giá trị NULL hoặc một giá trị NULL với bất kỳ giá trị khác, mã của bạn sẽ trả về một kết quả không rõ.

Trong khi khái niệm tự nó đánh giá để unknown mã của bạn trả về một kết quả hoàn toàn xác định khi bạn hiểu rằng bất cứ so sánh =, <>, >, < vv với NULL đánh giá như Unknown và rằng mệnh đề WHERE chỉ trả lại hàng nơi biểu thức đánh giá thành true.

Có thể chúng có nghĩa là nếu ANSI_NULLS bị tắt nhưng ví dụ mà chúng đưa ra trong tài liệu của WHERE ISNULL([c2],0) > 2;WHERE [c2] > 2; sẽ không bị ảnh hưởng bởi cài đặt này. Cài đặt này

chỉ ảnh hưởng đến so sánh nếu một toán hạng so sánh là hoặc biến NULL hoặc NULL.

kế hoạch Thực hiện cho thấy quét vs tìm kiếm hoặc dưới

CREATE TABLE #foo 
    (
    x INT NULL UNIQUE 
) 

INSERT INTO #foo 
SELECT ROW_NUMBER() OVER (ORDER BY @@SPID) 
FROM sys.all_columns 

SELECT * 
FROM #foo 
WHERE ISNULL(x, 10) = 10 

SELECT * 
FROM #foo 
WHERE x = 10 

SELECT * 
FROM #foo 
WHERE x = 10 
     OR x IS NULL 

enter image description here

+0

rằng cú pháp trong 'khoản TRÌNH TỰ BY' là gì? (Tôi đã googled nhưng nó hơi khó để google cho ...) – AakashM

+0

@AakashM - Đó là cách gõ ít nhất tôi đã tìm thấy cho đến nay đặt hàng bởi một hằng số để chỉ nhận được một chuỗi tăng dần các số. 'over (thứ tự bởi (SELECT 0))' hoặc 'over (thứ tự bởi @@ spid)' là các lựa chọn thay thế. Bạn không thể sử dụng một giá trị hằng số bằng chữ như SQL Server cung cấp cho bạn một lỗi. Việc chia cho số không ngăn cản nó được coi là một hằng số theo nghĩa đen. Bạn không thể sử dụng '1/0' như sau đó SQL Server những thứ bạn đang cố gắng để đặt hàng bởi một cột nguyên thứ tự và ném một lỗi. –

+0

Ồ, tôi thấy, '$' được hiểu là chữ 'tiền' có giá trị bằng 0! Đó là sự hào phóng đáng ngạc nhiên từ trình phân tích cú pháp, tôi phải nói :) – AakashM

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