2011-09-25 58 views
2

我有一個約38萬行的SQL表。加速SQL到Linq ToList

在SQL SMSS我執行此查詢:

SELECT Longitude, Latitude, street FROM [Stops].[dbo].[Members] 
WHERE ABS(Latitude - 51.463419) < 0.005 AND ABS(Longitude - 0.099) < 0.005 

它返回約20個結果幾乎瞬間。

我有一個WCF webserice揭露我的數據我的Windows Phone應用程序:

public class Service1 : IService1 
{ 
    double curLatitude = 51.463; 
    double curLongitude = 0.099; 

    public List<Member> GetMembers() 
    { 
     DataClassesDataContext db = new DataClassesDataContext(); 
     var members = from member in db.Members        
where (Convert.ToDouble(member.Latitude) - curLatitude) < 0.005 && (Convert.ToDouble(member.Longitude) - curLongitude) < 0.005 

select member; 
     return members.ToList(); 
    } 
} 

我相信這是做相同的查詢,而且還增加了項目列表。

問題是,它需要7+分鐘,然後我得到一些奇怪的異常,所以永遠不會完成。 VS2010中的WCF服務測試人員只是填滿了內存,並在執行此操作時使用了大量的CPU。 我的感覺是ToList在做些奇怪的事情?

+2

只需添加:您可能想要查看「實時」分析工具;例如,我們使用(和寫)「mvc-mini-profiler」來確保我們總是可以直接訪問數據庫的每個***查詢,以及參數值,時間點,行數,重複等然後我們可以輕鬆地檢查是否有任何意外發生。影響幾乎爲零(它必須是;我們對性能非常非常挑剔)。例如,我可以一目瞭然地告訴你多少SQL查詢(以及哪個TSQL)用於構建此頁面,以及每個頁面需要多長時間。 –

回答

3

您錯過了LINQ版本中的絕對部分。

一些附註。
您可以至少以兩種可能的方式跟蹤SQL查詢。

  1. 使用SQL事件探查器並檢查那裏的查詢(然後您可以將查詢粘貼到SQL Management Studio中並將輸出與上面的查詢進行比較)。
  2. 插入db.Log = Console.Out;(或另一個TextWriter)並檢查Visual Studio中的輸出窗口。

你應該配置你的DataClassesDataContext,最好的辦法是把它放在一個用塊:

public List<Member> GetMembers() 
{ 
    using(DataClassesDataContext db = new DataClassesDataContext()) 
    { 
     var members = from member in db.Members        
     where (Convert.ToDouble(member.Latitude) - curLatitude) < 0.005 
      && (Convert.ToDouble(member.Longitude) - curLongitude) < 0.005 
     select member; 
     return members.ToList(); 
    } 
} 
+0

是的,我添加了Math.Abs​​。現在加載一秒鐘。否則它可能會返回6000個結果。我現在覺得很傻:-) –

+0

@Ash,刪除abs會返回世界的一半或類似的東西。返回類似100.000條記錄需要比返回7更多的時間。絕對部分將其縮小到非常接近實際位置的點。 –

+0

實際上67,000個結果;-) –

2

有一些問題在這裏:

  • (編輯:忽略此點;我誤解了380,000作爲被提取的數據),這是一個非常大的數據量來查詢和帶來網絡;例如,查詢分析器需要多長時間?在將其加載到LINQ-to-SQL中時,您至少需要很長的任何時間才能處理實體開銷和身份管理器開銷;後者可以通過禁用對數據上下文的對象跟蹤來解決;前者更棘手 - 如果你懷疑這是顯着的(有時候可能是這樣),也許像「精靈」這樣的東西可以加載它(它具有更高效的物化器,並且不包括身份管理器)
  • WCF has將這些數據序列化,這可能需要相當多的CPU和內存 - 然後需要通過網絡(需要帶寬)。如果你可以自由改變格式,其他序列化器可能會在這裏保存CPU和帶寬。

所以;首先要做的是確定時間在哪裏。

  • 我會從查詢分析器運行它開始;也許索引缺失?
  • 集之後ObjectTrackingEnabled假
  • ,分開WCF數據訪問,看看哪個纔是罪魁禍首 - 時間只是數據到一個列表一步
  • 後,時間的DataContractSerializer連載本數據並在序列化時測量數據的大小(個人,然後我會比較protobuf網 - 但這可能不是一個選項,具體取決於您的情況)
  • 然後測量網絡上的時間

任何或所有這些可能需要在這裏優化。

+0

感謝您的評論。事實證明,它只是用C#中的查詢返回太多結果。什麼是查詢分析器?我還沒有找到。 –

+0

@Dan Query Analyzer是用於編寫,測試和優化SQL查詢的理想工具SQL Server Management Studio的舊名稱(對不起,我的錯誤) –

+0

Query Analyzer是一箇舊工具,現在已被SQL Management Studio取代。 –