簡體   English   中英

EF Core 查詢非常慢,表之間有很多關系

[英]EF Core query is extremely slow with many relations between tables

我有一個這樣的 EF Core 查詢:

var existingViolations = await _context.Parent
       .Where(p => p.ProjectId == projectId)
          .Include(p => p.Relation1)
          .Include(p => p.Relation2)
               .ThenInclude(r => r.Relation21)
          .Include(p => p.Relation3)
        .AsSplitQuery()
        .ToListAsync();

此查詢通常需要 55-65 秒,這有時會導致數據庫超時。 查詢中包含的所有表(包括父表)都包含 30k-60k 行和 3-6 列。 我嘗試使用LoadAsync()將其拆分為較小的查詢,如下所示:

_context.ChangeTracker.LazyLoadingEnabled = false;
_context.ChangeTracker.AutoDetectChangesEnabled = false;

await _context.Relation1.Where(r1 => r1.Parent.ProjectId == projectId).LoadAsync();

await _context.Relation2.Where(r2 => r2.Parent.ProjectId == projectId).Include(r2 => r2.Relation21).LoadAsync();

await _context.Relation3.Where(r3 => r3.Parent.ProjectId == projectId).LoadAsync();

var result = await _context.Parent.Where(p => p.ProjectId == projectId).ToListAsync();

這將查詢時間縮短了大約 5 秒,所以沒什么可吹噓的。 我已經做了一些計時,這是迄今為止完成時間最長的最后一行( var result = await _context.Parent.Where(p => p.ProjectId == projectId).ToListAsync(); ),大約 90花費時間的百分比。

我該如何進一步優化呢?

在沒有看到真實實體以及它們如何配置的情況下,這是任何人的猜測。

一般來說,在查看此類性能問題時,我首先要解決的是“加載這些數據的目的是什么?” 通常,當我看到使用大量Include的查詢時,這類似於基於所選數據為視圖或計算加載的讀取操作。 如果您真的只需要每個表中的幾列來滿足您的需求,那么投影到更簡單的 model 在這里會大有幫助。 在相關數據中使用Select進行投影以填充 DTO/ViewModel class 用於視圖或匿名類型用於計算的好處是, Include將希望傳遞一個 Z34D1F91 中所有急切加載表的所有列,其中 FB12E514B98576A,投影只會傳回引用的列。 當表可以包含您根本不需要或立即不需要的大型文本/二進制列之類的內容時,這可能非常重要。 這在數據庫服務器可能與消費客戶端或 web 服務器有一定距離的情況下也非常重要。 網絡上的數據越少 = 性能越快,盡管現在的問題聽起來像是數據庫查詢本身。

接下來要檢查的是所有表和 EF 中的任何相關配置與表設計之間的關系。 等待一分鍾從 30-60k 行中提取幾條記錄的時間太長了,我高度懷疑某些不使用 FK/索引的有缺陷的關系映射。 另一個值得關注的地方是對數據庫運行分析器以捕獲正在運行的確切 SQL 語句,然后手動執行這些語句以調查其執行計划,這可能會揭示架構問題或實體關系映射產生的一些怪異導致效率非常低查詢。

接下來要檢查的是使用消除過程來查看是否存在不良關系。 一個一個地消除每個急切的加載Include語句,看看每個查詢場景需要多長時間。 如果有一個特定的Include導致急劇減速,請深入研究該關系以了解原因。

這應該給你幾個途徑來檢查。 考慮使用實際實體和任何進一步的故障排除結果修改您的問題。

暫無
暫無

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

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