【问题标题】:Optimizing LINQ queries - How can I improve the execution time?优化 LINQ 查询 - 如何提高执行时间?
【发布时间】:2023-03-11 10:49:08
【问题描述】:

我想知道是否有优化我的 LINQ 查询的好方法。我正在使用类似于以下内容的 LINQ 查询从数据库中检索数据:

// PKs is a list of integers   
var import = context.table.Where(x => PKs.Contains(x.PrimaryKey)).AsEnumerable();

我(错误地)假设这会导致如下 SQL 调用:

SELECT * from table where PrimaryKey in (PK[1], PK[2], ...)

即 1 个数据库命中。使用Glimpse 检查 SQL 调用,我看到 LINQ 查询被翻译成许多单独的 SQL 调用,例如:

SELECT * from table where PrimaryKey=PK[1]
SELECT * from table where PrimaryKey=PK[2]
...

单个查询的执行速度非常快,但由于我的整数列表很大(以千计),开销造成的偏移导致查询需要大约 25 秒才能运行。

我决定通过数据库调用去除耗时的 LINQ 查询,并通过存储过程调用导入数据:

var import = this.p_import(parameter).ToList();

这极大地缩短了响应时间,因为只有一次数据库调用,从大约 25 秒缩短到不到 1 秒。

这解决了我的问题,但我使用 LINQ 的全部原因是为了避免使用存储过程。有没有更好的方法可以优化我的 LINQ 查询?

【问题讨论】:

  • 你可以使用context.table.Where(x => x.PrimaryKey==PK[1] || x.PrimaryKey==PK[2]).AsEnumerable();
  • 将数千个对象作为查询的命令参数传递是错误的。您应该将它们保存在单独的表中,索引列并进行有效连接。
  • PK的内容从何而来?
  • 您使用的是 Linq2Sql 还是 Linq2Entities。哪个版本的 EF?
  • EF 4,Linq2Entities。谢谢spender,我会将您的答案标记为正确!

标签: c# sql linq entity-framework


【解决方案1】:

如果你改为加入,事情应该会顺利很多。

context.table.Join(PKs,t => t.PrimaryKey, pk => pk, (t, pk) => t).AsEnumerable()

Linq2Sql 不支持将实体加入 POCO 列表,只是用 EF 测试过,一切都很好。

使用 Linq2Sql,您会被 Contains 卡住,在这种情况下,我可能会选择带有表值参数的存储过程。

【讨论】:

    【解决方案2】:

    EF 4 应该支持 IN 查询翻译。我从来没有遇到过 EF 中包含的问题,但似乎早期版本不能正确支持它。

    You can find more details and a possible solution here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-10
      • 2021-07-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多