2017-05-07 45 views
0

我創建的ASP MVC項目從大Mysql數據庫獲取數據〜500000LINQ和.Count之間的大數據庫

我的DataTable添加到我的前端與各列的過濾器,其中只顯示10個條目。

enter image description here

data = dc.books.OrderBy(x => x.id).Where(x => 
     (market_id == 0 || x.market_id == market_id) 
     && (name == null || x.name != null && (x.name.Contains(name))) 
     && (author == null || x.author != null && (x.author.Contains(author))) 
    ).Skip(param.Start).Take(10).ToList(); 

工作又好又快。

當我嘗試添加計數後過濾器綁好。不工作服務器Mysql超時錯誤或工作非常緩慢

count = db.books.Count(x => 
        (market_id == 0 || x.market_id != 0 && x.market_id == market_id) 
        && (name == null || x.name != null && (x.name.StartsWith(name))) 

爲什麼計數不工作或緩慢?

所有代碼我conttoller here

+0

Sql Server的計數速度非常快(還有謂詞)。無論計數是否快速,它在數據庫引擎中可能都是根深蒂固的。我不知道MySql,但我認爲你錯過了一些重要的索引。 –

回答

0

你最好這樣做:

var query = db.books.AsQueryable(); 

if (market_id!=0) 
    query = query.Where(x=>x.market_id==market_id); 

if (name!=null) 
    query = query.Where(x=>x.name.StartsWith(name)); 

count = query.Count(); 
data = query 
    .OrderBy(x=>x.id) 
    .Skip(param.Start) 
    .Take(10) 
    .ToList(); 

並非所有的LINQ提供商非常好的優化了過濾器,並將它們傳遞到數據庫。許多數據庫將爲這些類型的查詢生成可怕的查詢計劃,並生成最不嚴重的查詢計劃,並將其重用於所有類似查詢,這將錯過使用索引的可能性使用上面的代碼。

在很多情況下,你可能還需要限制算的,所以你可以這樣做:

count = query.Take(1001).Count(); 

那麼如果計數== 1001然後使用郵件「的超過1000個結果。」

0

這一切都歸結到數據庫是如何工作的,什麼樣的SQL被最終生成。 StartsWith被轉換爲通配符搜索,這可能比簡單的查詢慢。你可以嘗試使用索引來幫助你試圖優化的特定查詢,並且你可以查看生成的SQL來檢查它是否和你期望的一樣好(有時它會產生奇怪的SQL,但是這看起來像一個簡單的查詢,所以我不會太擔心這一點)。您可能還需要檢查是否有任何區別在生成的SQL如果你加括號的或表達式的部分分開,就像name == null || (x.name != null && (x.name.StartsWith(name)))