2010-05-01 55 views
1

我使用LINQ to SQL和看到我的CPU使用率天空rocketting會發生什麼。看下面的截圖。我有三個問題的LINQ to SQL:太多的CPU使用率:當有多個用戶

  • 我該怎麼做才能減少CPU使用率。我已經完成了分析並基本刪除了所有內容。將每個LINQ to SQL語句轉換爲編譯查詢有幫助嗎?

  • 我還發現,即使使用編譯查詢,ByID()等簡單語句在3.25GB RAM 3.17GHz的服務器上可能需要3毫秒 - 這在功能不太強大的計算機上會變得更慢。或者編譯後的查詢速度越快,使用得越多?

  • 單個用戶的CPU使用率(在本地服務器上達到12-15%)會與訪問服務器的用戶數相乘 - 當應用程序被置於實時服務器上時。即一次有2個用戶將意味着15 * 2 = 30%的CPU使用率。如果是這樣的話,那麼我的應用程序一次最多隻能有4-5個用戶。或者不LINQ to SQL .net共享一些CPU使用率。 alt text http://www.freeimagehosting.net/uploads/5f10e1f694.png

+1

索引,索引,索引... – 2010-05-01 07:21:02

+1

您可以發佈您認爲是導致問題的查詢的SQL嗎? – 2010-05-01 07:44:28

+1

你的SQL Server在同一臺機器上嗎?你確定LINQ to SQL(.NET)在吃你的CPU,還是你的SQL Server? – Steven 2010-05-01 07:56:48

回答

6

簡介。簡介。簡介。

檔案,以找出究竟哪些查詢花費最多的資源,提高該查詢的性能。您可以使用DataContext的Log屬性查看SQL - 請參閱this article。您可以在SQL Server中獲取查詢的查詢計劃 - 請參閱this article。方式

例子來提高查詢:

  • 添加缺少的索引。
  • 重寫查詢以利用已經存在的索引。
  • 不要爲每個查詢獲取太多數據 - 使用分頁並且只有在請求時才獲取更多行。不要獲取不需要的字段。
  • 不要爲每個查詢獲取太少數據 - 不要一次一個循環獲取一行。一次取多行。

一旦你這樣做了,再次配置文件來檢查你是否改進了該查詢的性能。如果沒有,重複,直到你有。

然後再配置文件,看看下一個殺手級的查詢是什麼,直到你的表現尚可重複上述過程。

你說你已經成型,但你還沒有發佈任何分析信息,如查詢,查詢計劃,執行時間,查詢頻率,等等。沒有更多分析數據,我們所能做的是猜測。

+0

索引什麼? SQL服務器中的表。 LINQ to SQL甚至關心表上的索引 - 它不適用於這裏http://social.msdn.microsoft.com/Forums/en-US/linqprojectgeneral/thread/ad8cc0d5-e1a3-4333-b0a1-1d67c406a6c7 – soldieraman 2010-05-01 07:28:18

+0

@soldieraman: LINQ to SQL將查詢表達式轉換爲SQL。 SQL服務器根據哪些索引可用並基於表的統計信息爲這些SQL語句創建查詢計劃。您可以通過將某些內容分配給您的上下文的Log屬性來記錄發送到數據庫的SQL語句。 – 2010-05-01 07:30:29

+1

LINQ參與數據庫的索引與任何其他外部實體 - 最終用戶,開發人員,ADO.NET,ODBC等相同。如果您已將索引創建爲數據庫模式的一部分,則LINQ將使用它們,因爲您的數據庫是已經設置好使用它們。 – 2010-05-01 07:33:29

1

編譯查詢不會「獲得更快」與更多的使用。編譯查詢的主要好處是可以節省LINQ引擎在每次調用時重複執行翻譯過程的需求。

至於CPU使用率,如果這是你的開發機,賠率是非常好的別的東西是怎麼回事造成這種高活性。即使這是專用的數據庫服務器,我也會強烈建議使用SQL Profiler來調查您的LINQ查詢生成的語句。它可能需要調整您的模式,代碼或數據庫設置,以使用量回到更可接受的水平。

0
  1. 是否有任何可以緩存的常見查詢?
  2. linq查詢是否可以重寫
  3. 大部分查詢處理是在Web服務器上還是在SQL中完成?
  4. 你在同一個盒子上運行SQL服務器和Web服務器嗎?你有一個模擬生產環境的測試環境嗎?
3

我注意到在這裏有一些應用程序的類似行爲;使用ANTS Profiler,我們已經將我們的CPU利用率縮小到了Linq to SQL代碼中。我們發現了幾個主要的地方,這成爲一個問題:

  1. 複雜的Linq到SQL查詢。使用幾個連接和where子句約束等。這些問題是Linq to SQL引擎必須將C#語句轉換爲SQL語句。我相信,如果相同的代碼由相同的DataContext調用,那麼默認情況下可以重新使用此轉換,但是如果您爲每次執行實例化新的DataContext,則每次都會執行CPU密集型轉換代碼。這可以通過用存儲過程或使用預編譯的Linq to SQL查詢(Here's a blog post showing how to create a compiled query)將複雜的Linq替換爲SQL查詢來解決。
  2. 基於反射的屬性分配。我們發現像DataContext.Orders.FirstOrDefault(o => o.OrderID = orderID)這樣的簡單查詢可能非常耗費CPU資源,因爲它們使用反射將所有屬性設置爲查詢中返回的值。除此之外,我們尚未對此進行調查。我們簡單地用一些手寫代碼將標準C#數據訪問(例如SqlCommand,SqlClient)中的一些Linq代碼替換爲基於SQL的代碼,以將適當的列數據拖入適當的屬性中,但僅限於ANTS告訴我們的地方重要。進行此更改通常會明顯降低CPU利用率(例如,從2000 ms的CPU利用率下降到39 ms)。
  3. 一般的Linq性能問題(並非Linq to SQL專用);雖然編寫Linq查詢確實比類似的迭代方法導致更多的意圖揭示代碼,但是我們發現有時查詢最終會變得非常低效(通常通過多次迭代集合或構建笛卡兒式產品,而真正不必要的) 。我沒有任何關於這個問題的例子,但是ANTS能夠幫助找到這些問題(通常針對特定代碼行尋找非常高的命中次數)。這些通常可以通過對Linq查詢進行小的調整來解決(或者在某些情況下用幾個語句替換Linq查詢)。

也許值得注意的是,我們使用Linq to SQL是基於GUI創建的DBML文件,因此使用包含列映射等所有信息的屬性裝飾類。

這正是我們發現的有關Linq to SQL;我很想看看其他人的經歷。我強烈推薦使用ANTS Performance Profiler來確定CPU利用率集中在應用程序中的哪個位置;請注意,如果CPU的高利用率是基於SQL的(它聽起來不像是你的情況),那麼ANTS可能不會有幫助(我的答案也不會)。

1

我們最近部署了一個使用linq到sql的大型電子商務應用程序,並且經歷了與您描述的非常相似的CPU使用情況。

經過幾周的分析和調試跟蹤,結果證明惡棍是在運行時查詢的jit編譯。

我們瀏覽了我們的數據層並將所有查詢轉換爲編譯查詢,並且當查詢第一次被編譯時,我們的CPU使用率從一個恆定的100%立即變爲平均5%到20%,並且一些尖峯高達80%。