C# 为什么SqlQuery比在视图上使用LINQ表达式快得多?

C# 为什么SqlQuery比在视图上使用LINQ表达式快得多?,c#,sql,entity-framework,oracle11g,C#,Sql,Entity Framework,Oracle11g,我想从一个视图中查询数据,该视图是一个包含583000条记录的表的视图。 因此,我编写了一个简单的查询,从如下视图进行查询 var uuid = "AB1-23456"; dbSet.SingleOrDefault(x => x.UserKey == uuid); var queryString = "SELECT \"Extent1\".\"UserKey\" AS \"UserKey\", " + "CAST( \"Extent1\".\"IsDel

我想从一个视图中查询数据,该视图是一个包含583000条记录的表的视图。 因此,我编写了一个简单的查询,从如下视图进行查询

var uuid = "AB1-23456";
dbSet.SingleOrDefault(x => x.UserKey == uuid);
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();
这是生成的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次查询。 在这个查询中,第一次调用花费了我350ms,接下来的调用平均花费了我150ms,这太慢了,所以我将查询更改为如下

var uuid = "AB1-23456";
dbSet.SingleOrDefault(x => x.UserKey == uuid);
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次 第一次通话花费了我40ms,接下来的通话平均只花费了1ms

有人知道我做错了什么吗

环境

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

    • 它第一次运行时只需要150毫秒,不是吗?。每一个连续的通话都应该在你所说的1毫秒左右。LinqToSql必须首先编译查询才能获得SQL。 看看
      此问题不再有效

      var uuid = "AB1-23456";
      dbSet.SingleOrDefault(x => x.UserKey == uuid);
      
      花费的时间约为150毫秒。但如果我试过

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

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

      这是这个问题的最佳答案


      这是可复制的吗?如果先使用新查询发送查询,会发生什么情况?生成的查询会是最快的吗?我非常怀疑您的“生成的sql”在这里是否正确表示。EF很可能使用参数,而不是像您所示在查询中嵌入字符串文字。@ErenErsönmez我使用LinqPad生成SQL语句,它向我显示了该语句。@nvoigt我尝试以不同的顺序调用这两个查询,结果仍然相同。您是否从LinqPad获得这些时间结果?因为如果您使用的是LinqPad,我认为您的linq查询不会被缓存。因此,实际上运行多少次并不重要(除了数据库端的查询计划缓存之外)。不,每次运行都是150ms。更清楚的是,我在没有重新启动进程的情况下运行了很多次,第一次调用花费了我350ms,下一次调用平均花费了我150ms。我发现EF5自动缓存查询。古怪的如果您使用字符串uuid=“AB1-23456”;,该怎么办?你试过查询表达式吗?e、 g.(从dbSet中的x开始,其中x.UserKey=uuid选择x);有什么区别吗只是好奇。@PaulZahra结果与.SingleOrDefault(x=>x.UserKey==uuid)相同。如果我改为stringliteral,结果与SingleOrDefault相同(x=>x.UserKey==“AB1-23456”);奇怪。。。这可能会让您感兴趣,我怀疑原因可能是因为它为查询构造缓存的方式,字符串文字将被定义为常量,变量将被参数化,尽管我看不出它有多大区别。