簡體   English   中英

實體框架-如何優化“包含”語句?

[英]Entity Framework - how can I optimize “Contains” statement?

在當前應用程序中,某些查詢存在一些性能問題。 通常我們有這樣的東西:

List<int> idList = some data here…;
var query = (from a in someTable where idList.Contains(a.Id));

雖然對於簡單查詢這是可以接受的,但是當我們在idList中有更多項時(例如,在某些查詢中,我們要檢查約700個ID)就會成為瓶頸。

有什么辦法可以使用包含以外的東西? 我們正在考慮使用一些臨時表先插入Ids,然后執行join而不是Contains,但是EntityFramework似乎不支持此類操作(在代碼中創建臨時表):(

我們還能嘗試什么?

我建議使用LINQ PAD,它提供了“轉換為SQL”選項,該選項使您可以用SQL語法查看查詢。

有可能這是最佳解決方案(如果您不喜歡雜亂的東西)。 可以嘗試將idList保留為已排序的數組,並用二進制搜索替換contains方法。 (您可以實現自己的擴展程序)。

如果您不介意使用物理表,則可以使用半臨時表。 基本思想是:

  1. 創建帶有“查詢ID”列的物理表
  2. 生成唯一ID(不是隨機 ID,而是唯一 ID)
  3. 將數據插入表中,以查詢ID標記記錄
  4. 將查詢ID傳遞給主查詢,並使用它加入鏈接表
  5. 查詢完成后,刪除臨時記錄

最壞的情況是,如果出現問題,鏈接表中將有孤立的記錄(這就是為什么使用唯一的查詢ID的原因)。

這不是最干凈的解決方案,但是如果您要檢查的值很多,它將比使用“ Contains更快。

當實體框架開始成為性能瓶頸時,通常是時候編寫實際的SQL了。

因此,例如,您可以做的是構建一個表值函數 ,該函數將一個表值參數 (您的ID列表)作為參數。 該函數將只返回JOIN的結果。

表值函數功能需要EF5,因此如果您確實對EF4感到困惑,則可能無法選擇它。

您可以嘗試以下方法:

var query = someTable.Where(a => idList.Any(b => b.Id == a.Id));

這個想法是重構查詢以擺脫idList

例如,您應該返回法國18至25歲男性用戶的訂單列表。 如果按年齡,性別和國家/地區過濾用戶表以獲取idList用戶列表,則最終會獲得700多個ID。 而是使Orders表與Users並將過濾器應用於Users表。 因此,您沒有2個請求(一個用於id,一個用於訂單),它的工作速度更快,因為它可以在加入表時使用索引。

說得通?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM