使用带日期参数的SqlCommand时,为什么会出现超时?

时间:2011-12-08 10:21:20

标签: c# sql sqlcommand

我的代码与此相似:

DateTime startDate = new DateTime(2010, 12, 1);
DateTime endDate = new DateTime(2011, 12, 1);
string sql = "SELECT * FROM SomeTable WHERE SomeDateColumn BETWEEN @StartDate AND @EndDate";

using (var connection = new SqlConnection(_connString))
using (var command = new SqlCommand(connection)) {
    command.Parameters.AddWithValue("@StartDate", startDate.Date);
    command.Parameters.AddWithValue("@EndDate", endDate.Date);

    using (var reader = command.ExecuteReader()) {
        // filling up some objects...
    }
}

这次超时。

只需更改SQL查询以在明文中包含日期,查询就可以正常运行。

string sql = "SELECT * FROM SomeTable WHERE SomeDateColumn BETWEEN '" + startDate.ToString("yyyy-MM-dd") + "' AND '" + endDate.ToString("yyyy-MM-dd") + "'";

使用VS2010中的查询连接,两个查询都运行得很快,但是一旦我在我的程序中尝试它,第一个就会因为超时而失败。

这种行为有解释,还是我错过了什么?

3 个答案:

答案 0 :(得分:1)

@enddate参数在哪里。不应该像

DateTime startDate = new DateTime(2010, 12, 1); 
DateTime endDate = new DateTime(2011, 12, 1); 

答案 1 :(得分:1)

原因是SQL Server的查询优化器在选择索引时没有考虑参数值。

因此,它不知道您的BETWEEN子句是选择1行,10行还是数十亿行,因此选择表扫描。

当您在SQL语句中嵌入日期作为文字时,优化程序会获得所需的所有信息,以便选择正确的索引。

您可以做的是query hints。如果您知道此查询的典型用例涉及几行,例如一周的跨度,您可以将该知识嵌入到SQL中:

SELECT * FROM SomeTable WHERE SomeDateColumn BETWEEN @StartDate AND @EndDate
OPTION (
    OPTIMIZE FOR @StartDate = '<some date here>`,
                 @EndDate = '<some other date here>`
)

您还应该确保最近在该表上涉及的索引上重新计算了统计信息,以帮助查询优化器选择有用的索引。

答案 2 :(得分:0)

根据查询是否包含参数,将确定查询优化器如何生成执行计划。使用文字,它将使用参数生成所提供值的最佳计划,它将根据我对统计信息中表中数据的了解,为可以提供的值生成最佳计划。

为这些日期列创建一些统计信息和索引可能有助于提高param查询的性能。