gpt4 book ai didi

c# - 使用 SqlCommand 参数时调用 SQL 函数要慢得多

转载 作者:太空狗 更新时间:2023-10-29 20:37:14 28 4
gpt4 key购买 nike

我正在从我的 C# ASP.Net 应用程序调用 SQL 函数 (UDF)。我调用的函数需要一个“uniqueidentifier”类型的参数。

如果我调用并在 SqlCommand 的 CommandText 中传递“null”,结果将在大约 3 秒内返回...

SqlCommand Command = new SqlCommand();
Command.Connection = (SqlConnection)(DbDataModifier.CreateConnection());
Command.CommandText = "select * from GetLocalFirmLoginsSummary(null) order by Date asc"
Command.CommandType = CommandType.Text;

Command.Connection.Open();

SqlDataReader Reader = Command.ExecuteReader(); // takes 3 seconds

但是,如果我进行调用并将 DBNull.Value 作为 SqlParameter 传递,结果需要 60 多秒才能返回...

SqlCommand Command = new SqlCommand();
Command.Connection = (SqlConnection)(DbDataModifier.CreateConnection());
Command.CommandText = "select * from GetLocalFirmLoginsSummary(@CustomerGroupID) order by Date asc"
Command.CommandType = CommandType.Text;

SqlParameter Param = new SqlParameter();
Param.ParameterName = "@CustomerGroupID";
Param.SqlDbType = SqlDbType.UniqueIdentifier;
Param.Direction = ParameterDirection.Input;
Param.IsNullable = true;
Param.Value = DBNull.Value;
Command.Parameters.Add(Param);

Command.Connection.Open();

SqlDataReader Reader = Command.ExecuteReader(); // takes over 60 seconds

如果我在 SQL Management Studio 中运行相同的查询,它需要大约 3 秒,即使将 null 作为参数传递...

declare @CustomerGroupID uniqueidentifier
set @CustomerGroupID = null

select * from GetLocalFirmLoginsSummary(@CustomerGroupID)

我调用的函数定义为:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[GetLocalFirmLoginsSummary]
(
@CustomerGroupID uniqueidentifier
)
RETURNS TABLE
AS
RETURN
(

SELECT CustomerGroupID, CustomerGroupName, USR, DATEADD(MONTH, DATEDIFF(MONTH, 0, createdDate), 0) AS Date, COUNT(*) AS Quantity
FROM dbo.GetLocalFirmLogins(@CustomerGroupID) AS Logins
GROUP BY USR, CustomerGroupID, CustomerGroupName, DATEADD(MONTH, DATEDIFF(MONTH, 0, createdDate), 0)

)

...

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[GetLocalFirmLogins]
(
@CustomerGroupID uniqueidentifier
)
RETURNS TABLE
AS
RETURN
(

SELECT vw_CustomerGroupAccountDetails.CustomerGroupID, vw_CustomerGroupAccountDetails.CustomerGroupName, Organisations.USR, Organisations.town AS FirmTown,
Users.id AS ID, Users.userName, Users.password, Users.isPartner, Users.isFeeEarner, Users.nlisUserName, Users.nlisPassword, Users.email, Users.lastLoginDate, Users.createdDate
FROM vw_CustomerGroupAccountDetails RIGHT OUTER JOIN
Organisations ON vw_CustomerGroupAccountDetails.AccountID = CAST(Organisations.id AS nvarchar(50)) RIGHT OUTER JOIN
Users ON Organisations.clientId = Users.uploadedBy
WHERE (Users.canLogin = 1) AND (Users.isDeleted = 0) AND (NOT (Organisations.USR IS NULL)) AND
((vw_CustomerGroupAccountDetails.CustomerGroupID = @CustomerGroupID) OR (@CustomerGroupID IS NULL))

)

那么,当我使用 SqlCommand 的 SqlParameter 从 C# 调用 SQL 函数时,是什么导致它花费如此长的时间?

我正在使用 SQL Server 2000。

我到处搜索,用我能想到的每一种方式,但找不到其他人有相同的问题。

最佳答案

吉姆,你能发布 dbo.GetLocalFirmLogins 的源代码吗?

正如 Martin 所说,这可能是参数嗅探。如果是,代码中的查询提示在其中查找 @CustomerGroupID 可能是“外科手术”解决此问题的最佳方法。

可以在此处修复向 dbo.GetLocalFirmLogins 中的查询添加 OPTION(LOOP JOIN)。

我想我也可以解释为什么 SSMS 看不到问题,而 C# 可以。这部分查询:

(CustomerGroupID = @CustomerGroupID) OR (@CustomerGroupID IS NULL) 

可能有两个不同的计划,具体取决于您来自的连接的 ANSI NULL 设置。 ANSI NULL,效果在此处描述:

SET ANSI_NULLS

您可以通过检索此查询的结果来查看连接的 ANSI 设置:

DBCC USEROPTIONS

SSMS 可能具有您使用 C# 编码的不同 NULL 设置,并导致对查询的不同评估。

关于c# - 使用 SqlCommand 参数时调用 SQL 函数要慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11034755/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com