这是我的主要问题:
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。这是必要的。
注意:在所有搜索列上创建索引,包括FirstName,LastName等。
谢谢!
答案 0 :(得分: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
另外如果你可以放弃这个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