2011-11-01 33 views
2

我在Linq上遇到了Windows Phone 7上的SQL性能問題,但我真的不知道我在做什麼錯了(我幾乎沒有Linq的經驗SQL,而我讀得越多,我越感到困惑感嘆)。非常慢的Linq到SQL在WP7上選擇性能

背景

我有五桌,兩列各(int主鍵& nvarchar值,加上索引)本地SQL CE數據庫,以及有關在每個表100,000項。該數據庫大小約爲20MB,遵循Microsoft自己的MVVM本地數據庫示例中的指導原則實施。

問題

簡化爲盡我所能,我有我的視圖模型的查詢,看起來像這樣:

var query = 
(
    from t1 in db.table1 
    join t2 in db.table2 on t1.id equals t2.id 
    join t3 in db.table3 on t1.id equals t3.id 
    join t4 in db.table4 on t1.id equals t4.id 
    join t5 in db.table5 on t1.id equals t5.id 
    where 
    SqlMethods.Like(t5.value, "%"+searchTerm+"%") 
    select new Results 
    { 
    Field1 = t1.value, 
    Field2 = t2.value, 
    Field3 = t3.value, 
    Field4 = t4.value, 
    Field5 = t5.value, 
    } 
).Take(100); 

SearchResults = new ObservableCollection<Results>(query); 

該產品的SQL語句:

SELECT TOP (100) 
    [t0].[value] AS [Field1], 
    [t1].[value] AS [Field2], 
    [t2].[value] AS [Field3], 
    [t3].[value] AS [Field4], 
    [t4].[value] AS [Field5] 
FROM 
    [table1] AS [t0], 
    [table2] AS [t1], 
    [table3] AS [t2], 
    [table4] AS [t3], 
    [table5] AS [t4] 
WHERE ([t4].[value] LIKE @p0) 
    AND ([t0].[id] = [t4].[id]) 
    AND ([t0].[id] = [t3].[id]) 
    AND ([t0].[id] = [t2].[id]) 
    AND ([t0].[id] = [t1].[id]) 

問題是,當搜索詞非常具體(只有一個結果)時,它的平均值大約爲5 seco nd執行。這是在添加任何其他需求之前,比如多個where子句,排名,排序等。即使我搜索我知道的數據庫中的第一行,仍然需要大約5秒。

如果我改變方法和搜索一些非常常見的東西(如'the'),它只需要大約100ms執行。我知道Like與通配符比直接==比較複雜,但我不知道爲什麼表現如此不同。 (我知道這是一個無用的比較,因爲它們是蘋果和桔子,但我之前對用MySQL編寫的相同數據庫執行了類似的查詢,並且無論我搜索的是什麼,它們的結果一直在0.3-0.4s左右對於)。

我是否錯過了一些非常明顯的東西?我已經關注了微軟的例子,並在線閱讀了很多教程,但是我無法找到爲什麼這個查詢太慢的原因。非常感謝您提供的任何建議。

+3

我強烈建議你嘗試執行相同的查詢*而不使用LINQ。*我懷疑*你會看到相同的性能,這意味着它不是LINQ應該歸咎於所有。請記住,通過這樣的通配符搜索,數據庫基本上不能使用任何索引 - 而在直接匹配的情況下,它應該能夠訪問正確的輸入非常迅速 –

+0

感謝您的快速回復,Jon。您說得對,我只是profi在我的桌面上使用生成的SQL引導了相同的數據庫,並獲得了類似的性能比(對於特定查詢爲1.2s,對於通用查詢爲0.02s)。我沒有意識到通配符會有很大的性能影響。 – Superangel

+0

@Superangel:Nice UserName。 –

回答

3

SIMPLE COMMON SENSE。

  • 您在低功率手機上運行該程序並進行表掃描查詢。

SqlMethods.Like(t5.value, 「%」 + SEARCHTERM + 「%」)

意味着沒有索引抓鬥,這是一個表掃描。

).Take(100);

表示:找到100個項目後停止。

現在,用一個非常常見的詞(「the」),這可能意味着只有100個項目被處理。用一個更不尋常的詞,它可能需要運行一半的表來獲得100個項目。表掃描一半數據庫將需要時間。 Simlpe。

一般來說,sql是爲文本中的文本解析做好準備的 - 這就是爲什麼真正的sql server需要全文索引。在低pwoer硬件上運行(%word%)(wp7 =自然很慢)

這裏指出LINQ是一個問題,絕對沒有任何問題,LINQ將它轉換爲一個相當有效的SQL查詢你在查詢中定義的邊界 - 這是你可以對數據庫做的最糟糕的事情,遺憾的是,

+0

謝謝湯姆,我認爲我的常識在盯着這麼長時間以後一直低迷!你的解釋非常清楚,我想我只是想過(希望?),不知怎的,我對Linq的理解缺乏責任。我想我需要重新制定我的查詢和/或數據以避免這種通配類型的情況,但我很掙扎。無論如何,感謝您的時間,並指出什麼應該是明顯的:) – Superangel