基礎數據庫查詢優化

昨天檢查一位小兄弟的代碼,發現執行起來很慢,就找找原因優化一下。

項目是C# WebForm  +  SQLSERVER  +  EF 的。開了 SQLSERVER 的 PROFILER 監聽,發現有連續幾條 READS (硬盤讀取次數)在3萬左右的記錄。查詢的語句如下:

SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        COUNT(1) AS [A1]
        FROM [dbo].[Customers] AS [Extent1]
        WHERE ((DATEDIFF(d, [Extent1].[AddTime], GetDate())) <= 30) AND (5 = [Extent1].[SectionId])
    )  AS [GroupBy1]

語義大概是查詢客戶表,添加時間在30天內,部門ID是5的記錄數量。這個表有幾十萬條記錄,根據兩個字段查數量,READS高肯定是沒有經過優化。根據這個查詢來找一下程序段,如下:

p => SqlFunctions.DateDiff("d", p.AddTime, DateTime.Now) <= 30 && p.SectionId == 5;

第一步,建立索引。由於使用這兩個字段執行查詢的地方很多,所以索引要建。我建立了一個索引,字段就是 AddTime 和 SectionId ,沒有包含性字段。建立好後執行同樣的語句,READS 降到了 1000 左右。雖然成功減少到30分之一,但和理想中的查詢還是差很多。

第二步,優化語句。SqlFunctions 的調用肯定沒有  < > = 這些比較符快,所以這裏需要改一下。思考一下改成如下:

var d = DateTime.Now.AddDays(-30);
p => p.AddTime >  d && p.SectionId == 5;

再執行一下,生成的SQL語句如下:

SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        COUNT(1) AS [A1]
        FROM [dbo].[Customers] AS [Extent1]
        WHERE ([Extent1].[AddTime] > convert(datetime, '2016-11-29 18:06:27.889', 121)) AND (5 = [Extent1].[SectionId])
    )  AS [GroupBy1]

READS 成功降到了個位數。 這樣就沒什麼問題了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章