2011-12-08 52 views
1

我有類似下面的代碼:爲什麼在使用帶有日期參數的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查詢連接,這兩個查詢運行速度快,但只要我嘗試它在我的程序,第一個失敗,因爲它超時。

對這種行爲有解釋嗎,還是我錯過了什麼?

+0

SomeDateColumn是什麼列類型?因爲你在發送「日期」,但是當查詢解析器解析'YYYY-MM-DD'時,它可能會將它解析爲DateTime,這可能會影響你的索引?只是一個長鏡頭。然而,如果索引是基於另一種數據類型的話,最理想的情況是能夠轉換日期。 – jishi

+1

啓動sql分析器並查看正在執行的查詢。 – Pleun

+0

@jishi - 列類型是'datetime'。 – jovnas

回答

1

原因是SQL Server的查詢優化器在選擇索引時沒有考慮參數值。

因此,它不知道您的BETWEEN子句將選擇1行,10行還是bazillion行,從而選擇表掃描。

當您將日期作爲文字嵌入到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>` 
) 

你也應該確保統計有最近重新計算了該表所涉及的索引,以幫助查詢優化器選擇有用的索引。

+0

請注意,我不是T-SQL的專家。可能有一些比上述更好的方法來處理這個問題,但是從經驗來看,這對我來說很有效。 –

+1

你的帖子讓我思考,所以我看着可用的指數。我結束了使用'WITH(INDEX(SomeTableIndex))',其中包括日期列。 – jovnas

1

@enddate參數在哪裏。不應該像

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

複製/粘貼錯誤...修復了原始文章。 – jovnas

0

取決於查詢是否包含參數將決定查詢優化器如何生成執行計劃。使用文字,它將生成所提供的值的最佳計劃,並且會生成最佳計劃,以便根據我對統計信息表中數據的瞭解提供最佳計劃。

可能爲這些日期列創建一些統計信息和索引將有助於提高param查詢的性能。

相關問題