簡體   English   中英

EF Core 和 MySql 查詢太慢

[英]EF Core and MySql query is too slow

我在 mysql 中有 2 個名為市場和交易所的表。
交換表中大約有 150 萬條記錄。
我想從交易所表中獲取每個市場最高更新日期的記錄。 作為查詢的結果,我想返回一個列表,其中每個市場只有一個最近的更新。
我使用 linq 創建了如下查詢。 但他的反應非常緩慢。
大約 7-8 分鍾。 我該如何解決這個問題?

感謝您的回答。

var query = (from exchange in _context.Exchanges
             join market in _context.Markets on exchange.MarketId equals market.Id
             where market.TypeId == 1
             group exchange by exchange.MarketId into grp

             let maxdate = grp.Max(x => x.LastUpdatedDateTime)

             from exchanges in grp
             where exchanges.LastUpdatedDateTime == maxdate
             select new DtoGetAllMarketsWithLastExchanges
             {
                 Id = exchanges.MarketId,
                 Code = exchanges.Markets.Code,
                 Name = exchanges.Markets.Name,
                 LastBuyPrice = exchanges.LastBuyPrice,
                 LastSellPrice = exchanges.LastSellPrice,
                 SeoUrl = exchanges.Markets.SeoUrl,
                 Icon = exchanges.Markets.Icon,
                 LastUpdateDate = exchanges.LastUpdatedDateTime,
                 Rate = exchanges.Rate
             }).ToList();

市場實體類;

[Table("Markets")]
public partial class Markets : BaseEntity
{
    public int TypeId { get; set; }

    public string Code { get; set; }

    public string Name { get; set; }

    public byte Unit { get; set; }

    public int OrderNumber { get; set; }

    public string Icon { get; set; }

    public string SeoUrl { get; set; }

    public virtual List<Exchanges> Exchanges { get; set; }
}

交易所實體類;

[Table("Exchanges")]
public partial class Exchanges : BaseEntity
{
    public int MarketId { get; set; }

    public double LastBuyPrice { get; set; }

    public double LastSellPrice { get; set; }

    public double Rate { get; set; }

    public DateTime CreatedDateTime { get; set; }

    public DateTime LastUpdatedDateTime { get; set; }

    [ForeignKey("MarketId")]
    public virtual Markets Markets { get; set; } 

}

查詢很慢,因為它使用了當前不受支持的結構,這會導致客戶端評估 大數據的客戶端評估效率很低,這也是EF Core 3.0 中將其刪除的原因之一。

所以訣竅是找到支持的 LINQ 構造(轉換為 SQL 並執行服務器端)。 由於每個 EF Core 版本都支持不同的結構,我不能確切地說 2.0 支持哪一個,但在最新的 2.2 中,一般來說,請嘗試遵循以下簡單規則:

  • 盡可能在手動連接上使用導航屬性
  • 盡可能避免使用GroupBy

並始終檢查客戶評估警告。 在 3.0+ 中,無論如何它們都會是運行時異常,所以你必須找到一個可翻譯的結構。

以下是一些在 2.2.6 中工作的功能等效的 LINQ 查詢:

(1) 使用Max標准

from market in _context.Markets
where market.TypeId == 1
from exchange in market.Exchanges
where exchange.LastUpdatedDateTime == market.Exchanges.Max(e => (DateTime?)e.LastUpdatedDateTime)
select new DtoGetAllMarketsWithLastExchanges
{
    Id = market.Id,
    Code = market.Code,
    Name = market.Name,
    LastBuyPrice = exchange.LastBuyPrice,
    LastSellPrice = exchange.LastSellPrice,
    SeoUrl = market.SeoUrl,
    Icon = market.Icon,
    LastUpdateDate = exchange.LastUpdatedDateTime,
    Rate = exchange.Rate
}

(2) 與 (1) 相同,但使用!Any (SQL NOT EXISTS ) 條件:

where !market.Exchanges.Any(e => e.LastUpdatedDateTime < exchange.LastUpdatedDateTime)

(3) 與 (1) 相同,但join Max子查詢:

from market in _context.Markets
where market.TypeId == 1
from exchange in market.Exchanges
join lastExchange in _context.Exchanges
    .GroupBy(e => e.MarketId)
    .Select(g => new { MarketId = g.Key, Date = g.Max(e => e.LastUpdatedDateTime) })
on new { exchange.MarketId, Date = exchange.LastUpdatedDateTime }
equals new { lastExchange.MarketId, lastExchange.Date }
select new DtoGetAllMarketsWithLastExchanges
{
    Id = market.Id,
    Code = market.Code,
    Name = market.Name,
    LastBuyPrice = exchange.LastBuyPrice,
    LastSellPrice = exchange.LastSellPrice,
    SeoUrl = market.SeoUrl,
    Icon = market.Icon,
    LastUpdateDate = exchange.LastUpdatedDateTime,
    Rate = exchange.Rate
}

暫無
暫無

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

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