C# 从Oracle视图检索记录(在实体框架中)使用硬编码字符串值运行得很快,但使用字符串参数运行得很慢

C# 从Oracle视图检索记录(在实体框架中)使用硬编码字符串值运行得很快,但使用字符串参数运行得很慢,c#,oracle,entity-framework,parameters,C#,Oracle,Entity Framework,Parameters,我正在构建一个ASP.NET MVC 5应用程序,以便一次对2到12行进行只读访问。这些记录存储在Oracle 11中,并通过Entity Framework 6从Oracle中的视图进行访问。正如标题所说,硬编码值很快,但字符串参数很慢(下面的示例) 它运行得很快: public List<VW_COLLISIONS_TS> GetCollisions(string collisionMRN) { var collisions = (from c in TSP_C

我正在构建一个ASP.NET MVC 5应用程序,以便一次对2到12行进行只读访问。这些记录存储在Oracle 11中,并通过Entity Framework 6从Oracle中的视图进行访问。正如标题所说,硬编码值很快,但字符串参数很慢(下面的示例) 它运行得很快:

 public List<VW_COLLISIONS_TS> GetCollisions(string collisionMRN)
 {
       var collisions = (from c in TSP_Context.VW_COLLISIONS_TS
            where c.COLLISION_MASTER_RECORD_NUMBER.Equals("902770479")
                          select c).AsNoTracking();

       return collisions.ToList();
 }
我同事的看法是:“我认为,当你硬编码时,它被视为数字/整数;当你使用字符串时,它被视为varchar/text,然后也寻找空值。如果冲突\u主记录\u数字是数字/整数数据类型,试着使用冲突\u主记录\u数字作为整数变量。”

你们怎么看?[注意:目前,COLLISION\u MASTER\u RECORD\u编号在Oracle数据库中是一个varchar2'编号(无alpha)]

更新(已回答!): 根据Alexander V发布的内容(包括EF链接),我得出以下结论:

 var collisions = (from c in TSP_Context.VW_COLLISIONS_TS
                          where c.COLLISION_MASTER_RECORD_NUMBER == (DbFunctions.AsNonUnicode(collisionMRN))
                          select c).AsNoTracking();
我在上下文构造函数中添加了以下内容:

this.Configuration.UseDatabaseNullSemantics = true;

这很有效。

您需要检查sql查询在这两种情况下生成的内容

请在.ToList()调用之前尝试添加此项:

如果您可以将sql查询发回,我们将看到这里发生了什么

更新:(基于@R.Jo发布的sql查询更新)

我认为第二次查询中的性能问题与额外的空检查有关: 所以试着用
==“something”
代替
.Equals(“something”)
因为Equals可以为可空类型生成额外的空检查; 在这里,我们需要处理两种不同的数据类型,当您执行相等操作时,我们也希望避免这种情况。(见下面的例子)。 如果示例中的代码不起作用,请尝试以下操作:
UseDatabaseNullSemantics=true可能有帮助。
(请参阅此处的更多信息

编辑:

[#1 - with hard-coded string value]
Opened connection at 2/9/2017 9:48:29 AM -05:00
SELECT 
"Extent1"."PERSON_MASTER_RECORD_NUMBER" AS "PERSON_MASTER_RECORD_NUMBER", 
"Extent1"."VEHICLE_MODEL" AS "VEHICLE_MODEL", 
"Extent1"."PERSON_AGE" AS "PERSON_AGE"
FROM "DWOBDEV"."VW_COLLISIONS_TS" "Extent1"
WHERE ('902770479' = "Extent1"."COLLISION_MASTER_RECORD_NUMBER")
-- Executing at 2/9/2017 9:48:29 AM -05:00
-- Completed in 5 ms with result: OracleDataReader
Closed connection at 2/9/2017 9:44:29 AM -05:00

[2. With string parameter]
Opened connection at 2/9/2017 9:44:17 AM -05:00
SELECT 
"Extent1"."PERSON_MASTER_RECORD_NUMBER" AS "PERSON_MASTER_RECORD_NUMBER", 
"Extent1"."VEHICLE_MODEL" AS "VEHICLE_MODEL", 
"Extent1"."PERSON_AGE" AS "PERSON_AGE"
FROM "DWOBDEV"."VW_COLLISIONS_TS" "Extent1"
WHERE (("Extent1"."COLLISION_MASTER_RECORD_NUMBER" = :p__linq__0) OR (("Extent1"."COLLISION_MASTER_RECORD_NUMBER" IS NULL) AND   (:p__linq__0 IS NULL)))
-- p__linq__0: '902770479' (Type = Object)
-- Executing at 2/9/2017 9:44:17 AM -05:00
-- Completed in 12364 ms with result: OracleDataReader
Closed connection at 2/9/2017 9:48:29 AM -05:00
如果碰撞主记录号码,那么我们可以做类似的事情

public List<VW_COLLISIONS_TS> GetCollisions(string collisionMRN)
 {
       int collision = int.Parse(collisionMRN);
       var collisions = (from c in TSP_Context.VW_COLLISIONS_TS
            where .COLLISION_MASTER_RECORD_NUMBER == collision
                          select c).AsNoTracking();


       return collisions.ToList();
 }
public List GetCollisions(string collisionMRN)
{
int collision=int.Parse(collisionMRN);
var collisions=(来自TSP_Context.VW_collisions_TS中的c)
其中.COLLISION\u MASTER\u RECORD\u NUMBER==COLLISION
选择c).AsNoTracking();
返回冲突。ToList();
}

请让我知道它是否适合您。

谢谢!我会试试。我说的是Oracle 11,它实际上在Oracle 12中。@R.Jo与生成的SQL一起,请获取执行计划。进一步检查后,大部分运行时间都用于转换检索到的数据ToList().有什么建议吗?更具体地说,检索数据大约需要2-3秒,将其转换为列表大约需要12秒!
var sql = ((System.Data.Entity.Core.Objects.ObjectQuery)collisions)
            .ToTraceString();
public List<VW_COLLISIONS_TS> GetCollisions(string collisionMRN)
 {
       int collision = int.Parse(collisionMRN);
       var collisions = (from c in TSP_Context.VW_COLLISIONS_TS
            where .COLLISION_MASTER_RECORD_NUMBER == collision
                          select c).AsNoTracking();


       return collisions.ToList();
 }