2010-03-30 39 views
1

我有我在走了太多的時間C#正在執行一個查詢:編譯與LINQ查詢內置SQL函數

string Query = "SELECT COUNT(HISTORYID) FROM HISTORY WHERE YEAR(CREATEDATE) = YEAR(GETDATE()) "; 
Query += "AND MONTH(CREATEDATE) = MONTH(GETDATE()) AND DAY(CREATEDATE) = DAY(GETDATE()) AND USERID = '" + EmployeeID + "' "; 
Query += "AND TYPE = '5'"; 

我然後使用SqlCommand的命令=新的SqlCommand(查詢,連接)和SqlDataReader Reader = Command.ExecuteReader()來讀取數據。這從C#執行需要一分多鐘,但在SSMS中更快。

我從谷歌搜索看到,你可以用CompiledQuery做些事情,但我很困惑我是否仍然可以使用內置的SQL函數YEAR,MONTH,DAY和GETDATE。

如果任何人都可以向我展示如何使用內置函數創建和調用編譯查詢的示例,我將非常感謝!提前致謝。

+1

您是說從同一臺機器上運行的SSMS上花費一分鐘時間從C#運行的完全相同的SQL要快得多嗎? – Gabe 2010-03-30 21:07:25

+1

這與linq-to-sql有什麼關係? – 2010-03-30 21:08:39

+0

@gabe:是的,同一臺機器。 @Sam:對不起,如果我感到困惑。我對這個主題不是很瞭解,也不是我自稱的。我放下了Linq-To-Sql,因爲CompiledQuery庫位於System.Data.Linq中,我正在使用它來編譯SQL。這是否太過分了? – Brandi 2010-03-30 21:16:08

回答

2

即使你有一個索引在CREATEDATE上,它不會使用它。您需要將GETDATE()日期時間更改日期邏輯地板這樣的日子:

WHERE CREATEDATE>=DATEADD(day,DATEDIFF(day,0,GETDATE()),0) 
    AND CREATEDATE<DATEADD(day,DATEDIFF(day,0,GETDATE()),0)+1 ... 

當您使用功能上的一列,例如:YEAR(CREATEDATE),你防止使用的索引。

+0

太棒了!這固定了它。非常感謝你。 – Brandi 2010-03-30 22:04:48

3

編譯查詢不會幫助你在這裏不幸的是:編譯時間不可能是一分鐘的重要部分。我假設你已經有一個索引,其中包括部分或全部(createdate, userid, type)。如果不是,請添加索引。

一個可能的問題是,您使用函數將阻止正在使用的創建的索引,從而導致索引掃描或表掃描緩慢。重寫你的查詢來改用BETWEEN,它應該能夠使用索引。這會讓它變得更快。

另外,在查詢中使用EXPLAIN來查看它正在使用哪些索引(如果有的話)。在這裏發佈信息。

2

Linq to Sql並不是解決您的所有查詢性能問題的神奇工具。實際上它會產生類似的查詢。相反,請分析您的查詢以找出緩慢的位置,並通過調整查詢和/或調整索引來解決這些問題。

我也必須指出,這是一個不好的做法,這樣做:

AND USERID = '" + EmployeeID + "' " 

而是嘗試使用參數化查詢來代替。這意味着,而是你使用:

AND [email protected] 

然後,您設置的參數執行命令前(假設NVARCHAR(255),調整需求):

commmand.Parameters.Add("@UserId", SqlDbType.NVarChar, 255).Value = EmployeeID; 
+0

我不知道你可以做到這一點,它的幫助,謝謝! – Brandi 2010-03-30 21:27:17