Saeed.Elmi
چهارشنبه 10 مرداد 1386, 09:58 صبح
سلام.
من لازم دازم یک Query بنویسم که پارامتر های آن پویا باشد. این Query را به دو گونه زیر نوشتم و می خواستم از لحاظ Performance بدانم که کدام کارایی بالاتری دارند
چون referenceی برای ساختار و ساختمان SQLServer2005 در دسترس نداشتم.
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER PROCEDURE [Users].[Select_UserInfo]
@ID uniqueidentifier ,
@UserType tinyint ,
@RelationID uniqueidentifier ,
@Name nvarchar(50) ,
@Family nvarchar(50) ,
@SelectType TinyInt
AS
BEGIN
SET NOCOUNT ON;
Begin Try
Declare @SQL nvarchar(Max), @SQLWhere nvarchar(Max)
Set @SQLWhere='';
Set @SQL='Select '
if (@SelectType=1)
Set @SQL='
Users_UserInfo.ID,
Users_UserInfo.UserName ,
Users_UserInfo.UserType ,
Users_UserInfo.[Name] As Users_UserInfo_Name,
Users_UserInfo.Family ,
Users_UserInfo.Phone ,
Users_UserInfo.MobileNo ,
Users_UserInfo.Email ,
Users_UserInfo.AreaID ,
BaseInfo_Places_AreaID.[Name] As BaseInfo_Places_AreaID_Name,
Users_UserInfo.StreetID ,
BaseInfo_Places_StreetID.[Name] As BaseInfo_Places_StreetID_Name,
Users_UserInfo.SubStreetID ,
BaseInfo_Places_SubStreetID.[Name] As BaseInfo_Places_SubStreetID_Name,
Users_UserInfo.Number ,
Users_UserInfo.Active ,
Users_UserInfo.ExpirationDate'
Else
Set @SQL='
Users_UserInfo.ID
, Users_UserInfo.Name
, Users_UserInfo.Family
, Users_UserInfo.FatherName
, Users_UserInfo.IDNo
, Users_UserInfo.IDCode
, Users_UserInfo.PostalCode
, Users_UserInfo.BirthPlace
, Users_UserInfo.Job
, Users_UserInfo.Phone
, Users_UserInfo.MobileNo
, Users_UserInfo.Email
, Users_UserInfo.Web
, Users_UserInfo.MarriageStatus
, Users_UserInfo.AreaID
, BaseInfo_Places_AreaID.[Name] As BaseInfo_Places_AreaID_Name
, Users_UserInfo.StreetID
, BaseInfo_Places_StreetID.[Name] As BaseInfo_Places_StreetID_Name
, Users_UserInfo.SubStreetID
, BaseInfo_Places_SubStreetID.[Name] As BaseInfo_Places_SubStreetID_Name
, Users_UserInfo.Number
, Users_UserInfo.Gender'
Set @SQL='
From
Users.UserInfo Users_UserInfo
inner join BaseInfo.Places BaseInfo_Places_AreaID On BaseInfo_Places_AreaID.ID= Users_UserInfo.AreaID
inner join BaseInfo.Places BaseInfo_Places_StreetID On BaseInfo_Places_StreetID.ID=Users_UserInfo.StreetI D
inner join BaseInfo.Places BaseInfo_Places_SubStreetID On BaseInfo_Places_SubStreetID.ID=Users_UserInfo.SubS treetID'
if(@ID is Not Null)
Set @SQLWhere=@SQLWhere+' And Users_UserInfo.ID='+Cast(@ID as nvarchar(36))
if(@UserType is Not Null)
Set @SQLWhere=@SQLWhere+' And Users_UserInfo.UserType='+Cast(@UserType as nvarchar(3))
if(@RelationID is Not Null)
Set @SQLWhere=@SQLWhere+' And Users_UserInfo.RelationID='+Cast(@RelationID as nvarchar(36))
if(@Name is Not Null)
Set @SQLWhere=@SQLWhere+' And User_Userinfo.Name Like ''%'+@Name'%''';
if(@Family Is Not Null)
Set @SQLWhere=@SQLWhere+' And User_Userinfo.Family ''%'+@Family+'%''';
if @SQLWhere<>''
Set @SQL=@SQL+' Where '+SubString(@SQLWhere,5,Len(@SQLWhere)-4)
Execute SP_ExecuteSQL @SQL
End Try
Begin Catch
RaisError('00001',16,1)
RollBack TransAction
End Catch
END
و کد دوم:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER PROCEDURE [Users].[Select_UserInfo]
@ID uniqueidentifier ,
@UserType tinyint ,
@RelationID uniqueidentifier ,
@Name nvarchar(50) ,
@Family nvarchar(50) ,
@SelectType TinyInt
AS
BEGIN
SET NOCOUNT ON;
Begin Try
if (@SelectType=1)
Select
Users_UserInfo.ID,
Users_UserInfo.UserName ,
Users_UserInfo.UserType ,
Users_UserInfo.[Name] As Users_UserInfo_Name,
Users_UserInfo.Family ,
Users_UserInfo.Phone ,
Users_UserInfo.MobileNo ,
Users_UserInfo.Email ,
Users_UserInfo.AreaID ,
BaseInfo_Places_AreaID.[Name] As BaseInfo_Places_AreaID_Name,
Users_UserInfo.StreetID ,
BaseInfo_Places_StreetID.[Name] As BaseInfo_Places_StreetID_Name,
Users_UserInfo.SubStreetID ,
BaseInfo_Places_SubStreetID.[Name] As BaseInfo_Places_SubStreetID_Name,
Users_UserInfo.Number ,
Users_UserInfo.Active ,
Users_UserInfo.ExpirationDate
From
Users.UserInfo Users_UserInfo
inner join BaseInfo.Places BaseInfo_Places_AreaID On BaseInfo_Places_AreaID.ID= Users_UserInfo.AreaID
inner join BaseInfo.Places BaseInfo_Places_StreetID On BaseInfo_Places_StreetID.ID=Users_UserInfo.StreetI D
inner join BaseInfo.Places BaseInfo_Places_SubStreetID On BaseInfo_Places_SubStreetID.ID=Users_UserInfo.SubS treetID'
Where Cast(Users_UserInfo.ID as nvarchar(36)) Like '%'+Cast(@ID as nvarcharf(36))
And Cast(Users_UserInfo.UserType as nvarchar(3)) Like '%'+Cast(@UserType as nvarchar(3))
And Cast(Users_UserInfo.RelationID as nvarchar(36)) Like '%'+Cast(@RelationID as nvarchar(36))
And ...
else
Select
Users_UserInfo.ID
, Users_UserInfo.Name
, Users_UserInfo.Family
, Users_UserInfo.FatherName
, Users_UserInfo.IDNo
, Users_UserInfo.IDCode
, Users_UserInfo.PostalCode
, Users_UserInfo.BirthPlace
, Users_UserInfo.Job
, Users_UserInfo.Phone
, Users_UserInfo.MobileNo
, Users_UserInfo.Email
, Users_UserInfo.Web
, Users_UserInfo.MarriageStatus
, Users_UserInfo.AreaID
, BaseInfo_Places_AreaID.[Name] As BaseInfo_Places_AreaID_Name
, Users_UserInfo.StreetID
, BaseInfo_Places_StreetID.[Name] As BaseInfo_Places_StreetID_Name
, Users_UserInfo.SubStreetID
, BaseInfo_Places_SubStreetID.[Name] As BaseInfo_Places_SubStreetID_Name
, Users_UserInfo.Number
, Users_UserInfo.Gender'
From
Users.UserInfo Users_UserInfo
inner join BaseInfo.Places BaseInfo_Places_AreaID On BaseInfo_Places_AreaID.ID= Users_UserInfo.AreaID
inner join BaseInfo.Places BaseInfo_Places_StreetID On BaseInfo_Places_StreetID.ID=Users_UserInfo.StreetI D
inner join BaseInfo.Places BaseInfo_Places_SubStreetID On BaseInfo_Places_SubStreetID.ID=Users_UserInfo.SubS treetID'
Where Cast(Users_UserInfo.ID as nvarchar(36)) Like '%'+Cast(@ID as nvarcharf(36))
And Cast(Users_UserInfo.UserType as nvarchar(3)) Like '%'+Cast(@UserType as nvarchar(3))
And Cast(Users_UserInfo.RelationID as nvarchar(36)) Like '%'+Cast(@RelationID as nvarchar(36))
And ...
End Try
Begin Catch
RaisError('00001',16,1)
RollBack TransAction
End Catch
END
لطفا به این نکته توجه کنید که SP ها کامپایل شده ذخیره می شوند (مثل کد دوم) ولی کد دوم چون تمام دستورات در قالب یک رشته ایجاد شده اند، در زمان اجرا کامپایل می شوند، البته این برداشت من بوده است!!!
اگر این کد ها بررسی کنید خیلی ممنوم می شوم.!
من لازم دازم یک Query بنویسم که پارامتر های آن پویا باشد. این Query را به دو گونه زیر نوشتم و می خواستم از لحاظ Performance بدانم که کدام کارایی بالاتری دارند
چون referenceی برای ساختار و ساختمان SQLServer2005 در دسترس نداشتم.
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER PROCEDURE [Users].[Select_UserInfo]
@ID uniqueidentifier ,
@UserType tinyint ,
@RelationID uniqueidentifier ,
@Name nvarchar(50) ,
@Family nvarchar(50) ,
@SelectType TinyInt
AS
BEGIN
SET NOCOUNT ON;
Begin Try
Declare @SQL nvarchar(Max), @SQLWhere nvarchar(Max)
Set @SQLWhere='';
Set @SQL='Select '
if (@SelectType=1)
Set @SQL='
Users_UserInfo.ID,
Users_UserInfo.UserName ,
Users_UserInfo.UserType ,
Users_UserInfo.[Name] As Users_UserInfo_Name,
Users_UserInfo.Family ,
Users_UserInfo.Phone ,
Users_UserInfo.MobileNo ,
Users_UserInfo.Email ,
Users_UserInfo.AreaID ,
BaseInfo_Places_AreaID.[Name] As BaseInfo_Places_AreaID_Name,
Users_UserInfo.StreetID ,
BaseInfo_Places_StreetID.[Name] As BaseInfo_Places_StreetID_Name,
Users_UserInfo.SubStreetID ,
BaseInfo_Places_SubStreetID.[Name] As BaseInfo_Places_SubStreetID_Name,
Users_UserInfo.Number ,
Users_UserInfo.Active ,
Users_UserInfo.ExpirationDate'
Else
Set @SQL='
Users_UserInfo.ID
, Users_UserInfo.Name
, Users_UserInfo.Family
, Users_UserInfo.FatherName
, Users_UserInfo.IDNo
, Users_UserInfo.IDCode
, Users_UserInfo.PostalCode
, Users_UserInfo.BirthPlace
, Users_UserInfo.Job
, Users_UserInfo.Phone
, Users_UserInfo.MobileNo
, Users_UserInfo.Email
, Users_UserInfo.Web
, Users_UserInfo.MarriageStatus
, Users_UserInfo.AreaID
, BaseInfo_Places_AreaID.[Name] As BaseInfo_Places_AreaID_Name
, Users_UserInfo.StreetID
, BaseInfo_Places_StreetID.[Name] As BaseInfo_Places_StreetID_Name
, Users_UserInfo.SubStreetID
, BaseInfo_Places_SubStreetID.[Name] As BaseInfo_Places_SubStreetID_Name
, Users_UserInfo.Number
, Users_UserInfo.Gender'
Set @SQL='
From
Users.UserInfo Users_UserInfo
inner join BaseInfo.Places BaseInfo_Places_AreaID On BaseInfo_Places_AreaID.ID= Users_UserInfo.AreaID
inner join BaseInfo.Places BaseInfo_Places_StreetID On BaseInfo_Places_StreetID.ID=Users_UserInfo.StreetI D
inner join BaseInfo.Places BaseInfo_Places_SubStreetID On BaseInfo_Places_SubStreetID.ID=Users_UserInfo.SubS treetID'
if(@ID is Not Null)
Set @SQLWhere=@SQLWhere+' And Users_UserInfo.ID='+Cast(@ID as nvarchar(36))
if(@UserType is Not Null)
Set @SQLWhere=@SQLWhere+' And Users_UserInfo.UserType='+Cast(@UserType as nvarchar(3))
if(@RelationID is Not Null)
Set @SQLWhere=@SQLWhere+' And Users_UserInfo.RelationID='+Cast(@RelationID as nvarchar(36))
if(@Name is Not Null)
Set @SQLWhere=@SQLWhere+' And User_Userinfo.Name Like ''%'+@Name'%''';
if(@Family Is Not Null)
Set @SQLWhere=@SQLWhere+' And User_Userinfo.Family ''%'+@Family+'%''';
if @SQLWhere<>''
Set @SQL=@SQL+' Where '+SubString(@SQLWhere,5,Len(@SQLWhere)-4)
Execute SP_ExecuteSQL @SQL
End Try
Begin Catch
RaisError('00001',16,1)
RollBack TransAction
End Catch
END
و کد دوم:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER PROCEDURE [Users].[Select_UserInfo]
@ID uniqueidentifier ,
@UserType tinyint ,
@RelationID uniqueidentifier ,
@Name nvarchar(50) ,
@Family nvarchar(50) ,
@SelectType TinyInt
AS
BEGIN
SET NOCOUNT ON;
Begin Try
if (@SelectType=1)
Select
Users_UserInfo.ID,
Users_UserInfo.UserName ,
Users_UserInfo.UserType ,
Users_UserInfo.[Name] As Users_UserInfo_Name,
Users_UserInfo.Family ,
Users_UserInfo.Phone ,
Users_UserInfo.MobileNo ,
Users_UserInfo.Email ,
Users_UserInfo.AreaID ,
BaseInfo_Places_AreaID.[Name] As BaseInfo_Places_AreaID_Name,
Users_UserInfo.StreetID ,
BaseInfo_Places_StreetID.[Name] As BaseInfo_Places_StreetID_Name,
Users_UserInfo.SubStreetID ,
BaseInfo_Places_SubStreetID.[Name] As BaseInfo_Places_SubStreetID_Name,
Users_UserInfo.Number ,
Users_UserInfo.Active ,
Users_UserInfo.ExpirationDate
From
Users.UserInfo Users_UserInfo
inner join BaseInfo.Places BaseInfo_Places_AreaID On BaseInfo_Places_AreaID.ID= Users_UserInfo.AreaID
inner join BaseInfo.Places BaseInfo_Places_StreetID On BaseInfo_Places_StreetID.ID=Users_UserInfo.StreetI D
inner join BaseInfo.Places BaseInfo_Places_SubStreetID On BaseInfo_Places_SubStreetID.ID=Users_UserInfo.SubS treetID'
Where Cast(Users_UserInfo.ID as nvarchar(36)) Like '%'+Cast(@ID as nvarcharf(36))
And Cast(Users_UserInfo.UserType as nvarchar(3)) Like '%'+Cast(@UserType as nvarchar(3))
And Cast(Users_UserInfo.RelationID as nvarchar(36)) Like '%'+Cast(@RelationID as nvarchar(36))
And ...
else
Select
Users_UserInfo.ID
, Users_UserInfo.Name
, Users_UserInfo.Family
, Users_UserInfo.FatherName
, Users_UserInfo.IDNo
, Users_UserInfo.IDCode
, Users_UserInfo.PostalCode
, Users_UserInfo.BirthPlace
, Users_UserInfo.Job
, Users_UserInfo.Phone
, Users_UserInfo.MobileNo
, Users_UserInfo.Email
, Users_UserInfo.Web
, Users_UserInfo.MarriageStatus
, Users_UserInfo.AreaID
, BaseInfo_Places_AreaID.[Name] As BaseInfo_Places_AreaID_Name
, Users_UserInfo.StreetID
, BaseInfo_Places_StreetID.[Name] As BaseInfo_Places_StreetID_Name
, Users_UserInfo.SubStreetID
, BaseInfo_Places_SubStreetID.[Name] As BaseInfo_Places_SubStreetID_Name
, Users_UserInfo.Number
, Users_UserInfo.Gender'
From
Users.UserInfo Users_UserInfo
inner join BaseInfo.Places BaseInfo_Places_AreaID On BaseInfo_Places_AreaID.ID= Users_UserInfo.AreaID
inner join BaseInfo.Places BaseInfo_Places_StreetID On BaseInfo_Places_StreetID.ID=Users_UserInfo.StreetI D
inner join BaseInfo.Places BaseInfo_Places_SubStreetID On BaseInfo_Places_SubStreetID.ID=Users_UserInfo.SubS treetID'
Where Cast(Users_UserInfo.ID as nvarchar(36)) Like '%'+Cast(@ID as nvarcharf(36))
And Cast(Users_UserInfo.UserType as nvarchar(3)) Like '%'+Cast(@UserType as nvarchar(3))
And Cast(Users_UserInfo.RelationID as nvarchar(36)) Like '%'+Cast(@RelationID as nvarchar(36))
And ...
End Try
Begin Catch
RaisError('00001',16,1)
RollBack TransAction
End Catch
END
لطفا به این نکته توجه کنید که SP ها کامپایل شده ذخیره می شوند (مثل کد دوم) ولی کد دوم چون تمام دستورات در قالب یک رشته ایجاد شده اند، در زمان اجرا کامپایل می شوند، البته این برداشت من بوده است!!!
اگر این کد ها بررسی کنید خیلی ممنوم می شوم.!