这是SQL
SELECT tal.TrustAccountValue
FROM TrustAccountLog AS tal
INNER JOIN TrustAccount ta ON ta.TrustAccountID = tal.TrustAccountID
INNER JOIN Users usr ON usr.UserID = ta.UserID
WHERE usr.UserID = 70402 AND
ta.TrustAccountID = 117249 AND
tal.trustaccountlogid =
(
SELECT MAX (tal.trustaccountlogid)
FROM TrustAccountLog AS tal
INNER JOIN TrustAccount ta ON ta.TrustAccountID = tal.TrustAccountID
INNER JOIN Users usr ON usr.UserID = ta.UserID
WHERE usr.UserID = 70402 AND
ta.TrustAccountID = 117249 AND
tal.TrustAccountLogDate < '3/1/2010 12:00:00 AM'
)
基本上有一个 Users 表、一个 TrustAccount 表和一个 TrustAccountLog 表。
用户:包含用户及其详细信息
TrustAccount:一个用户可以拥有多个TrustAccount。
TrustAccountLog:包含对所有 TrustAccount“移动”的审计。一个
TrustAccount 与多个TrustAccountLog 条目关联。
现在,此查询在 SQL Server Management Studio 中以毫秒为单位执行,但由于某些奇怪的原因,它在我的 C# 应用程序中需要很长时间,有时甚至会超时(120 秒)。
这里是代码的简要说明。它在一个循环中被多次调用并且语句被准备好。
cmd.CommandTimeout = Configuration.DBTimeout;
cmd.CommandText = "SELECT tal.TrustAccountValue FROM TrustAccountLog AS tal INNER JOIN TrustAccount ta ON ta.TrustAccountID = tal.TrustAccountID INNER JOIN Users usr ON usr.UserID = ta.UserID WHERE usr.UserID = @UserID1 AND ta.TrustAccountID = @TrustAccountID1 AND tal.trustaccountlogid = (SELECT MAX (tal.trustaccountlogid) FROM TrustAccountLog AS tal INNER JOIN TrustAccount ta ON ta.TrustAccountID = tal.TrustAccountID INNER JOIN Users usr ON usr.UserID = ta.UserID WHERE usr.UserID = @UserID2 AND ta.TrustAccountID = @TrustAccountID2 AND tal.TrustAccountLogDate < @TrustAccountLogDate2 ))";
cmd.Parameters.Add("@TrustAccountID1", SqlDbType.Int).Value = trustAccountId;
cmd.Parameters.Add("@UserID1", SqlDbType.Int).Value = userId;
cmd.Parameters.Add("@TrustAccountID2", SqlDbType.Int).Value = trustAccountId;
cmd.Parameters.Add("@UserID2", SqlDbType.Int).Value = userId;
cmd.Parameters.Add("@TrustAccountLogDate2", SqlDbType.DateTime).Value =TrustAccountLogDate;
// And then...
reader = cmd.ExecuteReader();
if (reader.Read())
{
double value = (double)reader.GetValue(0);
if (System.Double.IsNaN(value))
return 0;
else
return value;
}
else
return 0;
最佳答案
根据我的经验,查询在 SSMS 中运行速度快而在 .NET 中运行速度慢的常见原因是连接的 SET
-ting 存在差异。当通过 SSMS 或 SqlConnection
打开连接时,会自动发出一堆 SET
命令来设置执行环境。不幸的是,SSMS 和 SqlConnection
具有不同的 SET
默认值。
一个常见的区别是 SET ARITHABORT
。尝试将 SET ARITHABORT ON
作为 .NET 代码中的第一个命令发出。
SQL Profiler 可用于监控 SSMS 和 .NET 发出了哪些 SET
命令,以便您发现其他差异。
以下代码演示了如何发出 SET
命令,但请注意,此代码尚未经过测试。
using (SqlConnection conn = new SqlConnection("<CONNECTION_STRING>")) {
conn.Open();
using (SqlCommand comm = new SqlCommand("SET ARITHABORT ON", conn)) {
comm.ExecuteNonQuery();
}
// Do your own stuff here but you must use the same connection object
// The SET command applies to the connection. Any other connections will not
// be affected, nor will any new connections opened. If you want this applied
// to every connection, you must do it every time one is opened.
}
关于c# - SQL 查询在 .NET 应用程序中很慢,但在 SQL Server Management Studio 中是瞬时的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2736638/