2010-01-05 50 views
3

我們最近開始使用complied查詢來提高我們的Linq to SQL設置的性能。有幾個查詢總是需要幾秒鐘的時間才能在第一次運行時在第二次運行中第一次運行。這似乎是因爲編譯實際上並沒有發生,直到第一次打電話。爲什麼我的編譯linq查詢第一次放緩?

是否有一種簡單的方法可以在編譯程序期間或至少在啓動過程中強制執行此編譯?

編輯: 所以從我看到的看來,它看起來像linq查詢是絕對不會編譯,直到進行調用。現在我正在寫我這樣的查詢:

static readonly Func<DataContext, int, IQueryable<Item>> getByPLUComp = 
    CompiledQuery.Compile<DataContext, int, IQueryable<Item>>((db, PLU) => 
      from i in db.Items 
      where i.IntPLU == PLU && i.Terminated == null 
      select i); 

我有一堆這些靜態只讀Funcs漂浮。有沒有一種簡單的方法,我可以讓我的程序運行並在啓動時將它們初始化,以便在那裏發生成本,而不是在正常使用期間發生?

編輯2: 我放棄這個問題之前的最後一次嘗試。爲了解決這個問題,我剛剛在程序的初始化過程中添加了對編譯查詢的調用。例如:

public void Initialize() 
{ 
    DataContext db = new DataContext(); 
    getByPLUComp(db, 0); 
} 

是否有更優雅的方式來強制編譯,而不僅僅是運行查詢並丟棄結果?

+0

你確定它不只是因爲你讓首次到數據庫的連接?或者說,延遲不是來自sql服務器端,這是一個緩存問題? – cyberconte 2010-01-05 20:15:52

+0

有問題的查詢不是應用程序運行的第一個查詢。問題也是一致的。每次程序運行時都會發生這種情況。 – Mykroft 2010-01-05 20:21:23

+2

你可能會發現這一系列的博客文章很有趣:http://blogs.msdn.com/ricom/archive/2007/06/22/dlinq-linq-to-sql-performance-part-1.aspx - 對編譯查詢進行編譯直到第一次使用纔會被編譯。其中一個帖子應該闡明爲什麼這項政策存在。 – jalf 2010-01-05 20:46:21

回答

0

服務器需要是第一次執行時的查詢計劃,然後使用緩存計劃進行後續執行。

1

在執行SQL數據庫將被緩存兩兩件事:

  1. 執行計劃
  2. 數據

執行計劃將保留在緩存中針對相同的查詢後續調用直到它「過期」。但是,由於數據保存在內存中,數據緩存通常會產生最大的性能差異,所以後續調用不需要訪問磁盤即可獲取。

+0

這是非常少量的數據,即使數據發生變化,通話時間也不會突然增加。那麼我的問題在SQL Server端呢? – Mykroft 2010-01-05 20:23:01

+0

我會這麼認爲,這是查詢實際執行的地方。我將運行SQL Profiler,監視進入的調用。查詢可能效率低下 - 我將檢查SQL實際正在執行的情況,檢查執行計劃。如果它真的效率低下/缺乏索引等,那麼這就是爲什麼即使是少量返回的數據,第一次運行速度明顯較慢的原因。 – AdaTheDev 2010-01-05 20:31:46

+0

我的印象是,這些調用花了這麼長時間的原因是由於將linq轉換爲sql而不是sql本身的執行所花費的時間。 – Mykroft 2010-01-05 20:36:30

0

Sql數據第一次將提高其他運行。 。 。您可以製作腳本,通過調用運行,以便兌現。您可以將其添加到安裝過程中。 。 。 。這可能有效。

您可以創建一個表來更新所需的信息。這種方式當你需要的信息可讀。 (如果將數據放在一起需要很多處理)