【问题标题】:Why is SqlQuery a lot faster than using LINQ expression on views?为什么 SqlQuery 比在视图上使用 LINQ 表达式快很多?
【发布时间】:2015-03-07 12:10:02
【问题描述】:

我想从一个视图中查询数据,这是一个包含 583,000 条记录的表的视图。 所以我写了一个简单的查询来像这样从视图中查询

var uuid = "AB1-23456";
dbSet.SingleOrDefault(x => x.UserKey == uuid);

这是生成的sql

SELECT "Extent1"."UserKey" AS "UserKey", 
       CAST("Extent1"."IsDeleted" AS number(3,0)) AS "C1", 
       "Extent1"."FirstName" AS "FirstName", 
       "Extent1"."LastName" AS "LastName", 
       "Extent1"."UserLogin" AS "UserLogin", 
       "Extent1"."AccLocationKey" AS "AccLocationKey", 
       "Extent1"."CompanyKey" AS "CompanyKey"
FROM "UsersView" "Extent1"
WHERE ('AB1-23456' = "Extent1"."UserKey")

我运行了 5 次查询。 第一次调用花了我 350 毫秒,下一次调用平均花了我 150 毫秒 这个查询太慢了,所以我把查询改成这样

var queryString = 
    "SELECT \"Extent1\".\"UserKey\" AS \"UserKey\", " +
            "CAST( \"Extent1\".\"IsDeleted\" AS number(3,0)) AS \"IsDeleted\", " +
            "\"Extent1\".\"FirstName\" AS \"FirstName\", " +
            "\"Extent1\".\"LastName\" AS \"LastName\", " +
            "\"Extent1\".\"UserLogin\" AS \"UserLogin\", " +
            "\"Extent1\".\"AccLocationKey\" AS \"AccLocationKey\", " +
            "\"Extent1\".\"CompanyKey\" AS \"CompanyKey\" " +
    "FROM \"UsersView\" \"Extent1\" " +
    "WHERE ('AB1-23456' = \"Extent1\".\"UserKey\")";
dbSet.SqlQuery(queryString).SingleOrDefault();

我运行了 5 次 第一次通话花费了我 40 毫秒,接下来的通话平均只花费了我 1 毫秒

有人知道我做错了什么吗?

环境

  • 实体框架 5.0
  • Oracle 11g 数据库
  • ODP.NET 11.2 第 3 版
  • .NET Framework 4.5

【问题讨论】:

  • 这是可重现的吗?如果您先使用新查询发送查询会发生什么?生成的查询会很快吗?
  • 我非常怀疑您的“生成的 sql”是否在此处准确表示。 EF 很可能会使用参数,而不是像您显示的那样在查询中嵌入字符串文字。
  • @ErenErsönmez 我使用 LinqPad 生成 SQL 语句,它向我展示了该语句。
  • @nvoigt 我试过以不同的顺序调用这两个查询,结果还是一样。
  • 您是否从 LinqPad 获得这些时间结果?因为如果您使用的是 LinqPad,我认为您的 linq 查询不会被缓存。因此,实际上运行多少次并不重要(除了可能在数据库端缓存查询计划)。

标签: c# sql entity-framework oracle11g


【解决方案1】:

不是说第一次运行只需要150ms吗?每次连续通话都应花费您所说的 1 毫秒左右。 LinqToSql 必须先编译查询才能获得 SQL。 看一眼 LinqToSql Precompiling queries benefit?

【讨论】:

  • 不,每次运行都是150ms。
  • 为了更清楚,我运行了很多次,没有重新启动进程,第一次调用花了我 350 毫秒,下一次调用平均花了我 150 毫秒。
  • 我发现EF5自动缓存了查询。 stackoverflow.com/questions/9739925/…
【解决方案2】:

这个问题不再有效。

var uuid = "AB1-23456";
dbSet.SingleOrDefault(x => x.UserKey == uuid);

花费的时间约为 150 毫秒。但是如果我尝试过

dbSet.SingleOrDefault(x => x.UserKey == "AB1-23456");

花费的时间回到1ms。我会相应地问另一个问题。

【讨论】:

  • 奇数...如果你使用 string uuid = "AB1-23456"; ?
  • 你试过查询表达式吗?例如(从 dbSet 中的 x 其中 x.UserKey = uuid 选择 x).SingleOrDefault();有什么不同吗? - 只是好奇。
  • @PaulZahra 结果与 .SingleOrDefault(x => x.UserKey == uuid) 相同。如果我更改为字符串文字,结果与 SingleOrDefault(x => x.UserKey == "AB1-23456");
  • 奇怪...这可能会让你感兴趣msdn.microsoft.com/en-gb/data/hh949853.aspx
  • 我怀疑原因可能是因为它为查询构造缓存的方式,字符串文字将被定义为常量,变量将被参数化,虽然我看不到它差别这么大。
【解决方案3】:

这是这个问题的最佳答案。

https://community.oracle.com/message/10481253

【讨论】:

    猜你喜欢
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多