使用ROW_NUMBER的SQL查询在LINQ中效率不高

本文关键字:LINQ 效率 查询 ROW NUMBER SQL 使用 | 更新日期: 2023-09-27 18:01:49

我在SQL中有这个查询:

SELECT * FROM (
    SELECT ROW_NUMBER() OVER (PARTITION BY p.category ORDER BY (
        SELECT AVG(CAST(r.users AS NUMERIC)) FROM description r WHERE r.company = p.id
    ) DESC)  AS rownb, p.* FROM company p 
) rs WHERE rownb <= 2

我把这个查询转换成LINQ的最远距离是:

Companies
    .SelectMany(r => 
        Descriptions
            .GroupBy(t => t.Company)
            .Select(t => new { 
                Average = t.Average(a => (double)a.Users), 
                Company = t.Key })
            .OrderByDescending(t => t.Average)
        , (p, r) => new { Companies = p, Descriptions = r })
    .Where(t => t.Companies.Id == t.Descriptions.Company)
    .GroupBy(t => t.Companies.Category)
    .Select(t => t.Take(2))
    .SelectMany(t => t)
    .Select(t => new { t.Companies.Name, t.Descriptions.Average, t.Companies.Category})
    .OrderBy(t => t.Category)

但问题是性能。SQL查询的成本是28%(相对于批处理),而LINQ查询的成本是72%。

我已经用LINQ中的SelectMany替换了Join,这减少了20%的成本。但是现在我不知道如何优化这个查询了。

另外,我知道LINQ中没有ROW_NUMBER。

我使用LINQPad来检查结果SQL查询。

问题:ROW_NUMBER是造成性能差异的原因吗?是否有可能进一步优化LINQ查询?

使用ROW_NUMBER的SQL查询在LINQ中效率不高

您可以像这样在select中模拟row_number

.Select((t,i) => new { rowindex = i+1, t.Companies.Name, t.Descriptions.Average, t.Companies.Category})

至于优化,我不太确定。