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.

SQL代码慢,不是SSMS

以下是我处理这些问题的经验。非常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的文章应该会引导您找到正确的方向。