代码之家  ›  专栏  ›  技术社区  ›  Aheho

使用COM互操作时.NET数据库调用缓慢,通过查询分析器调用快速

  •  1
  • Aheho  · 技术社区  · 15 年前

    我有一个旧的vb6应用程序,它使用COM/.NET interop调用这个查询。当它这样做的时候,它运行得比较慢。我使用SQL Profiler设置了一个跟踪,每个调用的持续时间在400ms-600ms之间。

    如果我通过查询分析器运行相同的查询,则会得到一个持续时间<30msASP.NET网站,使相同的确切呼叫,并得到持续时间小于30毫秒。

    通常我会怀疑COM/.NET互操作开销造成了延迟。不过,我要从SQL Profiler中获取跟踪时间。我看不出客户端的开销会对我从服务器端数据库跟踪得到的数据产生多大的影响。

    还有什么可能导致这个问题?

    编辑:

    我发现了这个问题。我设置了sql profiler来捕获执行计划,发现通过VB应用程序调用存储过程时,执行计划没有使用SSN上的索引。但是,当通过asp.net或者QA,调用适当的索引。我向服务器发送了一个sp\u重新编译,从那时起VB应用程序以足够的速度运行。

    我仍然不明白的是,为什么VB应用程序没有使用与其他客户端相同的缓存查询计划。

    1 回复  |  直到 15 年前
        1
  •  3
  •   Remus Rusanu    15 年前

    检查传递给SQL的参数(@SSN)的类型。通常情况下,参数是这样添加的:

    List<...> GetBySSN(string ssn) {
       SqlCommand cmd = new SqlCommand (@"select ... from ... where SSN=@SSN", conn);
       cmd.Parameters.AddWithValue("@SSN", ssn);
       using (SqlDataReader rdr = cmd.ExecuteQuery()) {
         ...
       }
    }
    

    不幸的是,这种模式增加了 @SSN NVARCHAR Data Type Precedence 需要将NVARCHAR和VARCHAR之间的比较作为NVARCHAR来完成,因此执行查询时就好像请求了以下SQL:

    select ... from ... where CAST(SSN as NVARCHAR) = @SSN;
    

    不同的 SSMS中的查询进行比较(它们使用VARCHAR参数或硬编码值)。

    如果这确实是问题所在,那么解决方案很简单:显式地将参数类型指定为 SqlDbType.VarChar