2013-03-06 13 views
0

4秒這是我的主查詢:加快此查詢?目前,它發生在100K行

exec sp_executesql N'set arithabort off;set transaction isolation level read uncommitted;Select COUNT(*) From (Select ROW_NUMBER() OVER 
           (Order By Case When d.OldInstrumentID IS NULL THEN d.LastStatusChangedDateTime Else d.RecordingDateTime End desc) peta_rn,  
           d.DocumentID 
           From Documents d 
           Inner Join Users u on d.UserID = u.UserID Inner Join IGroupes ig on ig.IGroupID = d.IGroupID 
           Inner Join ITypes it on it.ITypeID = d.ITypeID Where 1=1 ANd dbo.DoesNameExist(d.DocumentID, @0, @1, @2, @3) = 1 And (CreatedByAccountID = @4 
           Or DocumentStatusID = @5 
           Or DocumentStatusID = @6)) 
            v',N'@0 int,@1 varchar(4000),@2 varchar(4000),@3 nvarchar(4000),@4 int,@5 int,@6 int',@0=-999,@1='K',@2='Miller', 
            @3=NULL,@4=44,@5=5,@6=9 

,這是我的標量函數在罪魁禍首

ALTER FUNCTION [dbo].[DoesNameExist] 
(
    @DocumentID   int, 
    @PartyTypeID  int = 0, 
    @FirstName   varchar(30), 
    @LastName   varchar(30), 
    @Business   varchar(100) 
) 
RETURNS bit 
AS 
BEGIN 
    Declare @Found bit = 0 

    Set @FirstName = IsNull(@FirstName,'') 
    Set @LastName = IsNull(@LastName,'') 
    Set @Business = IsNull(@Business,'') 


    Select Top 1 @Found = 1 
     From DocumentNames 
      Where DocumentID = @DocumentID 
        And 
       Lower(IsNull(FirstName,'')) Like 
          Case When @FirstName = '' Then Lower(IsNull(FirstName,'')) + '%' 
           Else Lower(@FirstName) + '%' End 
        And 
       Lower(IsNull(LastName,'')) Like 
          Case When @LastName = '' Then Lower(IsNull(LastName,'')) + '%' 
           Else Lower(@LastName) + '%' End 
        And 
       Lower(IsNull(Business,'')) Like 
          Case When @Business = '' Then Lower(IsNull(Business,'')) + '%' 
           Else Lower(@Business) + '%' End 

        And 

       PartyTypeID = Case When @PartyTypeID IS NULL OR @PartyTypeID <= 0 Then PartyTypeID Else @PartyTypeID End 


    Return @Found 
END 

基本上一個文檔有多個DocumentNames和當用戶在LastName或FirstName中鍵入某些內容時,我想要帶有這些匹配名稱的所有文檔的計數。請注意,我正在查詢Documents表格,然後加入DocumentNames。這是必要的。

注:索引在所有的搜索欄,其中包括創建名字,姓氏等

謝謝!

+1

,如果您將函數體到主SQL語句會發生什麼?通常UDF是罪魁禍首,因爲引擎無法優化性能並最終做全表掃描 – cha 2013-03-06 06:20:44

+0

@cha:我很欣賞這個建議。但是,如何將它移入SQL語句中? – Jack 2013-03-06 06:23:52

+0

你能澄清一下嗎 - 你的第一個SQL只返回COUNT,而不是文檔列表。簡單看看你做了什麼,如果你使用IF EXISTS而不是調用你的函數,看起來你可以得到實質性的改進,因爲它看起來就是這樣做的。 – 2013-03-06 06:33:50

回答

3

首先,檢查Execution plan

IsNULL()正在如何使用?
查看所有IsNULL()的預計和實際時間。如果更多,則使用子查詢,您可以計算IsNULL()並提供給您的查詢。我們沒有你的Exceution plan。您也可以試試這個藏漢

ALTER FUNCTION [dbo].[DoesNameExist] 
(
    @DocumentID   int, 
    @PartyTypeID  int = 0, 
    @FirstName   varchar(30), 
    @LastName   varchar(30), 
    @Business   varchar(100) 
) 
RETURNS bit 
AS 
BEGIN 
    Declare @Found bit = 0 

    Select Top 1 @Found = 1 
     From DocumentNames 
      Where DocumentID = @DocumentID 
        And 
       Lower(IsNull(FirstName,'')) Like COALESCE(@FirstName,firstname,'')+'%' 
        And 
       Lower(IsNull(LastName,'')) Like COALESCE(@LastName,LastName,'')+'%' 
        And 
       Lower(IsNull(Business,'')) Like COALESCE(@Business,Business,'')+'%' 

        And 

       PartyTypeID = Case When @PartyTypeID IS NULL OR @PartyTypeID <= 0 Then PartyTypeID Else @PartyTypeID End 


    Return @Found 
END 

此外,如果你都OK放棄這個UDF,直接在語句中使用此與EXISTS條款應做的伎倆。

Select COUNT(*) From (Select ROW_NUMBER() OVER 
           (Order By Case When d.OldInstrumentID IS NULL THEN d.LastStatusChangedDateTime Else d.RecordingDateTime End desc) peta_rn,  
           d.DocumentID 
           From Documents d 
           Inner Join Users u on d.UserID = u.UserID Inner Join IGroupes ig on ig.IGroupID = d.IGroupID 
           Inner Join ITypes it on it.ITypeID = d.ITypeID Where 1=1 



           ANd EXISTS (
           Select 1 
           From DocumentNames 
            Where DocumentID = d.DocumentID 
              And 
             Lower(IsNull(FirstName,'')) Like COALESCE(@1,lower(firstname),'')+'%' 
              And 
             Lower(IsNull(LastName,'')) Like COALESCE(@2,lower(LastName),'')+'%' 
              And 
             Lower(IsNull(Business,'')) Like COALESCE(@3,lower(Business),'')+'%' 

              And 

             PartyTypeID = Case When @0 IS NULL OR @0 <= 0 Then PartyTypeID Else @0 End 




           ) 



           Or DocumentStatusID = @5 
           Or DocumentStatusID = @6)) 
            v',N'@0 int,@1 varchar(4000),@2 varchar(4000),@3 nvarchar(4000),@4 int,@5 int,@6 int',@0=-999,@1='K',@2='Miller', 
            @3=NULL,@4=44,@5=5,@6=9 
+0

您的版本在3秒內執行,但不夠好。 – Jack 2013-03-06 06:51:07

+0

你最後的陳述是什麼意思? *直接在您的語句中使用EXISTS子句應該可以做到這一點。*。任何樣品? – Jack 2013-03-06 06:57:57

+0

如何在不使用UDF函數的情況下在sql語句中存在if? – Jack 2013-03-06 06:58:26