SQL代码慢,不是SSMS
本文关键字:不是 SSMS 代码 SQL | 更新日期: 2023-09-27 18:06:48
我在处理c# . net 4.0中的一个非常大的表时遇到了问题。
作为参考,这个表有1.2亿行。
我甚至不能做一个简单的查询,比如
SELECT TOP(50) *
FROM TableName
WHERE CreatedOn < '2015-06-01';
从代码中它会超时(默认设置- 15秒我相信),但在SSMS是即时的。
WHERE子句中的列上有一个索引。我还尝试显式地将字符串转换为DateTime,并使用DateTime参数而不是文字值。
我尝试了一个不同的查询,通过PK (bigint, identity, clustered index)过滤,如果我做一些像"Where TableRowID = 1"这样的事情,它从代码中工作得很好,但如果我尝试使用"<"或"<="代替它将超时(在SSMS中立即返回),无论有多少行被翻转。
执行计划非常简单,与完全相同。我试过改变ARITHABORT,但没有效果。我尝试让应用程序连接到我自己的帐户(SSPI),而不是它自己的凭据,但没有效果。
我已经研究这个问题好几天了,但我发现的一切都归咎于不同的执行计划。
有没有人知道是什么导致了这个问题?
.Net代码是这样的:private DataSet ExecuteQuery(string query, string db, List<SqlParameter> parms = null)
{
string connectionString = ConfigurationManager.ConnectionStrings[db].ToString();
SqlConnection con = new SqlConnection(connectionString.Trim());
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
try
{
con.Open();
DataSet ds = new DataSet();
sqlDataAdapter.SelectCommand = new SqlCommand(query, con);
sqlDataAdapter.SelectCommand.CommandType = CommandType.Text;
if (parms != null)
{
foreach (SqlParameter p in parms)
{
sqlDataAdapter.SelectCommand.Parameters.Add(p);
}
}
sqlDataAdapter.Fill(ds);
if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
{
return ds;
}
return null;
}
finally
{
if (sqlDataAdapter != null)
sqlDataAdapter.Dispose();
if (con != null)
con.Dispose();
}
}
我在。net中得到的错误信息是标准超时消息:
Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
以下是我处理这些问题的经验。非常c#的sql代码传递给sql server就是选择top (50) *从表WHERE CreatedOn <"2015-06-01"
确定标准。如果在SSMS上检索记录需要"instant time",那么sql语句和db优化是ok的。
正如其他人指出的那样,你应该发布你的c#代码,看看会发生什么。可能还有其他问题。会是网络吗?会是web.config吗?直接从c#代码调用吗?你通过网络服务打电话吗?当你说暂停时?在执行查询时是否超时。你提供的信息很少。您是否使用第三方例程(例如由供应商或您的公司编写的例程)来执行查询?如果可能的话,将断点放在执行sql语句的代码处。我的意思是一直挖掘到本地代码,并放入中断代码。
1.2亿条记录。如果数据库在SSMS上运行得非常快,那么看起来它已经被优化了。我想看看SQL服务器之外的情况。
好运我的第一步是查看代码发送到sql server的内容。我将从运行sql分析器开始。如果你不熟悉的话。这里有一个如何使用它的链接。
https://www.mssqltips.com/sqlservertip/2040/use-sql-server-profiler-to-trace-database-calls-from-third-party-applications/在此之后,您可能想要查看两个服务器之间的网络流量时间。
然后看看IIS,看看它是如何设置的。可能是设置错了。
检查错误日志,看看是否也有错误
当您在SSMS中执行代码时,系统正在为您的连接设置一些默认值。具体来说,查看工具->选项->查询执行-> Sql Server ->高级(以及ANSI)。当您打开一个新的查询窗口时,这些语句将以您的名义执行。
当你在c#中创建连接对象时,你是否设置了这些相同的选项?如果不在这里显式地设置它们,则采用实际SQL Server实例中定义的默认值。在SSMS中,您可以通过查看服务器实例的属性并选择Connections页面来实现这一点。这显示了默认的连接选项。
您也可以在不使用UI的情况下获得此信息(例如,您可以在使用相同连接字符串的单独应用程序中执行此操作)。这篇关于MSSQLTips的文章应该会引导您找到正确的方向。