2011-01-19 61 views
1

我喜歡通過一堆輸入參數都默認爲NULL,然後那些相同的參數包含在WHERE中的存儲過程的數量與測試等於或空值。存儲過程的效率 - 空輸入參數和Where子句

這與查詢性能相關的效率如何 - 針對1個特定任務編寫存儲過程?例如通過用戶ID唯一,通過用戶名/密碼選擇,選擇的名字/姓氏選擇...

例子:

CREATE PROC dbo.up_Select_User 

    @UserId int = NULL 
, @Username varchar(255) = NULL 
, @Password varchar(255) = NULL 
, @FirstName varchar(50) = NULL 
, @LastName varchar(50) = NULL 
, @IsActive bit = NULL 


SELECT UserId, Username, FirstName, LastName, EmailAddress 
FROM dbo.[User] 
WHERE (UserId = @UserId OR @UserId IS NULL) 
AND (Username = @Username OR @Username IS NULL) 
AND (Password = @Password OR @Password IS NULL) 
AND (FirstName = @FirstName OR @FirstName IS NULL) 
AND (LastName = @LastName OR @LastName IS NULL) 
AND (IsActive = @IsActive OR @IsActive IS NULL) 

一些額外的信息 - 可能不相關的...我使用實體框架4根據查詢結果使用普通實體和複雜類型的混合映射到存儲過程。

回答

7

這是效率低下的,因爲它使用OR並且優化器將默認爲掃描。

如果你有幾行1000行,它會好的。

有時,這種模式效果更好,因爲ISNULL會變得微不足道

SELECT UserId, Username, FirstName, LastName, EmailAddress 
FROM dbo.[User] 
WHERE 
    UserId = ISNULL(@UserId, UserId) AND 
    Username = ISNULL(@Username , Username) AND 
    Password = ISNULL(@Password , Password) ... 
+0

OK爽 - 這樣我就可以逃脫它的低流量的交易與小記錄集 - 效率不高,但簡化了我的模型。但是當我需要高端性能時,我應該更加具體地瞭解我的參數,以儘可能避免OR子句。我想我也是這麼懷疑,或者我不會問這個問題,但是我不想做額外的工作,只是爲了發現沒有優勢,而且兩者都有效。感謝gbn :-) – Rob 2011-01-19 06:54:46

+0

@Rob:是的,對於更大的表格,你會寫更多的specfiic查詢。如果你有一個小的數據集,那麼你可以保持簡單。優化你當然需要的東西...在這種情況下,我假設你的用戶表沒有跟蹤這個星球上的每個人... – gbn 2011-01-19 07:01:40

+0

感謝隊友 - 實際上用戶proc是一個furphy - 我很少把真實的數據/代碼放在這些帖子;-) – Rob 2011-01-19 11:16:38

1

我們用這種方式來過濾

AND (CASE @UserId WHEN NULL THEN @UserId ELSE UserId END) = @UserId 

我們沒有與SqlServer的大數據的性能問題與解決方案。
某些應用程序視圖(如報告概述頁面)具有20多個過濾器設置,它適用於CASE WHEN構造。

編輯: 這些SET選項必須設置

SET QUOTED_IDENTIFIER OFF 
GO 
SET ANSI_NULLS OFF 
0

@gbn: 小心,與ISNULL版本是不完全一樣的。 例如 如果參數@firstName爲NULL

... AND (FirstName = @FirstName OR @FirstName IS NULL) 

不照顧姓值;結果包括記錄,其中名字爲NULL

... AND FirstName = ISNULL(@FirstName, FirstName) 

結果不包括記錄,其中名字爲NULL

相關問題