SqlCommand timeout even though in SQL Studio same query is fast

匿名 (未验证) 提交于 2019-12-03 08:52:47

问题:

I have what I thought was a simple query that I execute from my little log-processing application. The aim of this method is to simply get the highest date value out of the log table:

private DateTime GetLastEntryDate(string serverName, string siteName) {     DateTime dt = DateTime.MinValue;     using (var con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["LogParserDB"].ConnectionString))     {         con.Open();         using (var cmd = new SqlCommand("SELECT MAX(date) FROM iislogs WHERE host=@Host AND site=@Site", con))         {             cmd.CommandTimeout = 120;             cmd.Parameters.AddWithValue("Host", serverName);             cmd.Parameters.AddWithValue("Site", siteName);             var result = cmd.ExecuteScalar();             if (result != DBNull.Value)             {                 dt = (DateTime)result;             }         }     }     return dt; } 

There are some indexes on the table, but I'm not sure if that's relevant, because the problem I'm getting is that when I run this code, it throws a timeout after 2 minutes on the ExecuteScalar line.

If I copy and paste that query into SSMS with the same parameters, it completes in 00:00:04, or even 00:00:00 (if I've just updated stats).

SELECT MAX(date) FROM iislogs WHERE host='servername' AND site='W3SVC1' 

I have checked for blocking, and I can't see anything like that - that database is only being accessed by this one app, and it's not multi-threaded or anything like that.


Update: Interestingly, when I run the exact query as captured by Profiler, it also takes a long time in SSMS:

exec sp_executesql N'SELECT MAX(date) FROM iislogs WHERE host=@Host AND site=@Site',N'@Host nvarchar(13),@Site nvarchar(6)',@Host=N'servername',@Site=N'W3SVC1' 

The actual columns are varchar(50) and varchar(10) respectively.

回答1:

The query you execute in SSMS

SELECT MAX(date) FROM   iislogs WHERE  host = 'servername'        AND site = 'W3SVC1'  

Is not the same as the one executed by your application.

EXEC sp_executesql   N'SELECT MAX(date) FROM iislogs WHERE host=@Host AND site=@Site',   N'@Host nvarchar(13),@Site nvarchar(6)',   @Host=N'servername',   @Site=N'W3SVC1'  

The first one has varchar string literals. The second one has nvarchar parameters. Your column datatypes are in fact varchar.

nvarchar has higher datatype precedence than varchar so you are forcing an implicit cast of the column. This will render any indexes on the column useless.

Change the parameter datatypes in the application to varchar



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!