2009-10-08 23 views
16

Tôi đã chiến đấu với cái này trong một thời gian. Tôi có một proc được lưu trữ trong 3 thông số được sử dụng để lọc. Nếu một giá trị cụ thể được chuyển vào, tôi muốn lọc nó. Nếu -1 được thông qua, hãy cho tôi tất cả.T-SQL Trường hợp khoản Tối ưu hóa trường hợp khoản (tham số tùy chọn cho StoredProc)

Tôi đã thử nó trong hai cách sau:

cách đầu tiên:

SELECT field1, field2...etc 
FROM my_view 
WHERE 
parm1 = CASE WHEN @PARM1= -1 THEN parm1 ELSE @PARM1 END 
AND parm2 = CASE WHEN @PARM2 = -1 THEN parm2 ELSE @PARM2 END 
AND parm3 = CASE WHEN @PARM3 = -1 THEN parm3 ELSE @PARM3 END 

Thứ hai Way:

SELECT field1, field2...etc 
FROM my_view 
WHERE 
(@PARM1 = -1 OR parm1 = @PARM1) 
AND (@PARM2 = -1 OR parm2 = @PARM2) 
AND (@PARM3 = -1 OR parm3 = @PARM3) 

Tôi đọc ở đâu đó rằng cách thứ hai sẽ ngắn mạch và không bao giờ đánh giá phần thứ hai nếu đúng. DBA của tôi nói rằng nó buộc phải quét bảng. Tôi chưa xác minh điều này, nhưng có vẻ như chạy chậm hơn trong một số trường hợp.

Bảng chính mà chế độ xem này chọn có khoảng 1,5 triệu bản ghi và lượt xem tiến hành tham gia vào khoảng 15 bảng khác để thu thập một loạt thông tin khác.

Cả hai phương pháp này đều chậm ... đưa tôi từ tức thời đến bất kỳ đâu từ 2-40 giây, trong trường hợp của tôi hoàn toàn không thể chấp nhận được.

Có cách nào tốt hơn không liên quan đến việc chia nhỏ nó xuống từng trường hợp riêng biệt cụ thể so với -1 không?

Mọi trợ giúp đều được đánh giá cao. Cảm ơn.

Trả lời

6

Tôi đọc ở đâu đó rằng cách thứ hai sẽ ngắn mạch và không bao giờ đánh giá phần thứ hai nếu đúng. DBA của tôi nói rằng nó buộc phải quét bảng.

Bạn đã đọc sai; nó sẽ ngắn mạch không. DBA của bạn là đúng; nó sẽ không chơi tốt với trình tối ưu hóa truy vấn và có khả năng buộc quét bảng.

Tùy chọn đầu tiên là tốt nhất. Tùy chọn của bạn để cải thiện mọi thứ là sql động hoặc một thủ tục được lưu trữ lâu dài với mọi kết hợp có thể có của cột lọc để bạn có được kế hoạch truy vấn độc lập. Bạn cũng có thể thử sử dụng tùy chọn "WITH RECOMPILE", nhưng tôi không nghĩ rằng nó sẽ giúp bạn.

+0

Chết tiệt. Đánh tôi đi. +1 :) – DVK

+1

Tùy chọn đầu tiên sẽ không nhất thiết trả lại kết quả giống như kết quả thứ hai. Nếu bạn có các hàng trong bảng của bạn với các giá trị NULL, chúng sẽ KHÔNG được trả về bởi truy vấn "tùy chọn 1". Ví dụ .... Chọn * Từ Bảng Trường hợp NullableColumn = NullableColumn –

+0

Cả ba parm đều KHÔNG NULL, do đó, đó không phải là vấn đề trong trường hợp này. Có vẻ như tôi có thể bị kẹt với lựa chọn 1. – IronicMuffin

0

Không có cách nào khác tôi có thể nghĩ ra sau đó thực hiện:

ĐÂU

(MyCase IS NULL OR MyCase = @MyCaseParameter) VÀ ....

Điều thứ hai là đơn giản hơn và có thể đọc được với các nhà phát triển nếu bạn hỏi tôi.

+1

Nó cũng chậm như mật đường. Không sử dụng nó. –

+0

@Jelel bạn có gì để sao lưu điều đó không? Không phải là tôi nghi ngờ bạn, tôi chỉ tìm kiếm một số dữ liệu cứng một cách này hay cách khác. – Jonas

+0

Tôi có hai chỉ báo rằng phương pháp thứ hai có thể bắt buộc quét bảng và đó không phải là điều tốt với 1,5 triệu bản ghi. – IronicMuffin

2

Nếu bạn vượt qua trong một giá trị null khi bạn muốn tất cả mọi thứ, sau đó bạn có thể viết mệnh đề where của bạn như

Where colName = IsNull(@Paramater, ColName) 

này về cơ bản là tương tự như phương pháp đầu tiên của bạn ... nó sẽ làm việc miễn là cột chính nó không phải là nullable ... Các giá trị Null IN cột sẽ làm hỏng nó lên một chút.

Cách tiếp cận duy nhất để tăng tốc nó là thêm chỉ mục trên cột đang được lọc trong mệnh đề Where. Có ai chưa?Nếu không, điều đó sẽ dẫn đến một sự cải thiện đáng kể.

+0

Bạn có nghĩ rằng điều này sẽ tăng tốc không? Nó có vẻ như về cơ bản là hoạt động tương tự nhưng kiểm tra null thay vì -1. IsNull hiệu quả hơn một CASE? – IronicMuffin

+0

@IronicMuffin, (Tôi thích biệt danh của bạn) Không, bạn hoàn toàn đúng, điều này tương đương với phương pháp đầu tiên ... –

5

nếu bạn đang chạy SQL Server 2005 trở lên, bạn có thể sử dụng IF để tạo nhiều phiên bản truy vấn với đúng WHERE để chỉ mục có thể được sử dụng. Mỗi kế hoạch truy vấn sẽ được đặt trong bộ nhớ truy vấn.

cũng có, đây là một bài viết rất toàn diện về chủ đề này:

Dynamic Search Conditions in T-SQL by Erland Sommarskog

nó bao gồm tất cả các vấn đề và phương pháp cố gắng để viết các truy vấn với nhiều điều kiện tìm kiếm tùy chọn

ở đây là bàn nội dung:

 
    Introduction 
     The Case Study: Searching Orders 
     The Northgale Database 
    Dynamic SQL 
     Introduction 
     Using sp_executesql 
     Using the CLR 
     Using EXEC() 
     When Caching Is Not Really What You Want 
    Static SQL 
     Introduction 
     x = @x OR @x IS NULL 
     Using IF statements 
     Umachandar's Bag of Tricks 
     Using Temp Tables 
     x = @x AND @x IS NOT NULL 
     Handling Complex Conditions 
    Hybrid Solutions – Using both Static and Dynamic SQL 
     Using Views 
     Using Inline Table Functions 
    Conclusion 
    Feedback and Acknowledgements 
    Revision History
+0

+1 để liên kết mọi thứ bởi Mr Sommarskog –

+0

Đã đánh dấu ... cảm ơn bạn. Chúng tôi sử dụng kết hợp các máy chủ 2000/2005, tiếc là máy chủ này là 2000. – IronicMuffin

+0

bài viết bao gồm nhiều cách để xử lý các điều kiện tìm kiếm biến, IFs chỉ là một –

0

SQL 2008 và sau đó thực hiện một số cải tiến để tối ưu hóa cho những thứ như (MyCase IS NULL OR MyCase = @MyCaseParameter) AND ....

Nếu bạn có thể nâng cấp và nếu bạn thêm OPTION (RECOMPILE) để có được sự hoàn hảo cho tất cả các kết hợp param có thể (đây là trường hợp không có kế hoạch nào phù hợp cho tất cả các kết hợp param), bạn có thể thấy điều này hoạt động tốt.

http://blogs.msdn.com/b/bartd/archive/2009/05/03/sometimes-the-simplest-solution-isn-t-the-best-solution-the-all-in-one-search-query.aspx

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