2013-03-29 107 views
-1

我有以下LINQ查詢:LINQ到數據集,查詢優化

var itembind = (from q in dsSerach.Tables[0].AsEnumerable() 
      select new 
          { 
           PatternID = q.Field<int>("PatternID"), 
           PatternName = q.Field<string>("PatternName") + " " + q.Field<string>("ColorID") + q.Field<string>("BookID"), 
           ColorID = q.Field<string>("ColorID"), 
           BookID = q.Field<string>("BookID"), 
           CoverImage = (from img1 in objJFEntities.ProductImages.ToList() 
              where img1.PatternName.ToLower() == q.Field<string>("PatternName").ToLower() 
              select new CoverImage 
              { 
               URL = "Images/MediumPatternImages/" + 
                q.Field<string>("PatternName") + "_" + q.Field<string>("ColorID") + q.Field<string>("BookID") + q.Field<string>("ImageExtension"), 
               ID = q.Field<int>("ProductImageID") 
              }).FirstOrDefault(), 
           TotalCount = q.Field<int>("TotalCount") 
          }).Distinct(); 



var patterns = (from r in itembind 
      group r by new { r.PatternID, r.ColorID } into g 
      select new SearchPattern 
      { 
       PatternID = g.Key.PatternID, 
       PatternName = string.Join(",", g.OrderBy(s => s.ColorID).OrderBy(s => s.BookID) 
              .Select(s => String.Format("<a href='{0:s}' title='{1:s}'>{2:s}</a><br />", 
                new object[] { String.Format("Product.aspx?ID={0}&img={1}", g.Key.PatternID, s.CoverImage.ID), s.PatternName, s.PatternName })).FirstOrDefault()), 
       CoverImage = g.Count() > 1 ? (from img1 in objJFEntities.ProductImages.ToList() 
               where img1.ProductImageID == g.Select(i => i.CoverImage.ID).FirstOrDefault() && img1.ColorID.ToString() == g.Key.ColorID 

               select new CoverImage 
               { 
                URL = "Images/MediumPatternImages/" + 
                 img1.PatternName + "_" + img1.ColorID + img1.BookID + img1.ImageExtension, 
                ID = img1.ProductImageID 
               }).FirstOrDefault() : g.Select(i => i.CoverImage).FirstOrDefault() 


      }).ToList(); 

這些查詢正在採取更多然後1分鐘到執行只爲1000條記錄。 dsSearch是一個數據集,填充了SQL中從我的過程返回的記錄。 我正在使用實體框架。該網站使用IIS7.0進行部署。 SQL Server 2008正在使用中。

我「錯誤消息:超時過期之前,操作完成或服務器沒有響應超時時間已過。」 通過登錄「無法打開數據庫‘DB’請登錄失敗。 「。 &「底層提供程序在打開時失敗。」這種錯誤非常頻繁的網站。

請告訴我如何優化這樣的查詢。

編輯:

下面是該過程

http://pastie.org/7160934

+0

您確認您的連接字符串是正確的嗎?你在使用集成安全嗎? –

+0

是的,我驗證了這一點。在連接字符串 – Neha

+0

我不使用集成安全性的錯誤當然意味着其對數據庫超時,而不是查詢的連接(我覺得默認的超時時間爲60秒)。我會檢查連接和你的IIS設置。 –

回答

2

Rolfvm是指出objJFEntities.ProductImages引起該問題是正確的,但分析是一個有點不同。您獲取整個ProductImages表到內存每個迭代查詢,當您枚舉它。所以一個優化將是一個集合中的第一獲取圖像,並使用集合中的查詢語句

var localImages = objJFEntities.ProductImages.ToList(); 
... 
CoverImage = (from img1 in localImages.... 

不過,您的查詢似乎做太多。您在不執行它的情況下構建第一部分itembind。然後,你建立的第二部分(var patterns = (from r in itembind)和ToList()執行它。但在第二部分中,您從不使用第一部分中的CoverImage。所以創建這些是浪費資源。 (或者你刪除了代碼,隱藏了第一部分的另一個用法)。

+0

謝謝,推動收集分開作品,它現在需要以前的1/4的時間。我明白不同,非常感謝。請一次驗證我的程序,如果可以優化,也給我一個建議。 – Neha

+0

好吧,正如我所說的,我想知道爲什麼要創建'CoverImage'對象。你可以嘗試只抓取你需要的'ProductImages'。 –

+0

coverImage用於模式查詢以及我的用戶界面中的結果 – Neha

3

在第一個查詢你正在做一個objJFEntities.ProductImages.ToList(),與ToList()調用你取來自數據庫的每個條目,然後在內存中過濾結果。

+0

我嘗試刪除ToList()後。之後查詢將不會提供任何輸出。 – Neha

+0

但我敢打賭,查詢的性能好得多;)。 – Rolfvm

+0

但ToLower將()動作propably不會被映射到SQL的支持(不知道哪個DB您正在使用)。所以這取決於您使用的數據庫合併。 最好的事情,看看爲什麼你的查詢沒有返回任何結果是使用包含在SQL Management Studio中 – Rolfvm