我的代码与此相似:
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中的查询连接,两个查询都运行得很快,但是一旦我在我的程序中尝试它,第一个就会因为超时而失败。
这种行为有解释,还是我错过了什么?
答案 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查询的性能。