【问题标题】:SqlCommand slow when executing a query with parameters执行带参数的查询时 SqlCommand 很慢
【发布时间】:2013-01-14 13:13:53
【问题描述】:

DbDataAdapter.Fill() 在执行参数时非常慢!

我有一个内部有 2 个参数的查询,当我将这些参数硬编码到查询中时,执行需要 1 秒(在 470k 表行中,仅返回 20 行)。

我在这里发现了许多类似的帖子,但我尝试了所有这些解决方案(设置 arithabort、选项重新编译、选项优化……),但没有成功。

我只是执行查询(sql server 2008)而不是存储过程,所以使用arithabort的查询是这样的:

    string strSql = @"set ARITHABORT ON;
                             select  TOP 20 ....

我还尝试在同一个事务中调用 set arithabort 但首先执行该查询..

我不知道我是否做错了什么,但感觉是当我在 ado.net 上定义参数时,ado.net 在 ado.net 中执行了一个非常糟糕的执行计划。

由于这个错误的选择,SSMS 中的执行时间是 1 秒(缓存后),但在 asp 中是 9 秒!

查询是这样的:

strSQL @=" 选择 *
从表 1 其中名称如@name";

然后:

        DbProviderFactory factory = DbProviderFactories.GetFactory(mProvider);
        DbCommand dbcmd = factory.CreateCommand();
        if (CommandTimeout != null)
            dbcmd.CommandTimeout = CommandTimeout.Value;
        if(this.transaccion != null)
            dbcmd.Transaction = this.transaccion;
        dbcmd.Connection = dbc;
        dbcmd.CommandText = strSQL;
        if (parametros != null)
            dbcmd.Parameters.AddRange(parametros);
        DbDataAdapter dbda = factory.CreateDataAdapter();
        dbda.SelectCommand = dbcmd;
        DataTable dt = new DataTable();
        dbda.Fill(dt);
        return dt;

编辑 14/01/2013 (18:44)

我不再从 DbProviderFactory 检索连接,而是直接使用 SqlConnection 和 SqlCommand。我知道 DbCommand 和 DbProvider 是一个基类......但我认为那里还有更多......因为性能急剧提高了 300%!

这不是填充方法,因为我已经在前面显示的代码中尝试过..

无论如何,我不知道为什么但是使用 SqlConnection 更快!任何的想法?可能不是以前制定过那么糟糕的执行计划吗?

       SqlCommand objCmd = new SqlCommand(strSQL, sqlConn);

        if (CommandTimeout != null)
            objCmd.CommandTimeout = CommandTimeout.Value;
        if (this.transaccion != null)
            objCmd.Transaction = SQLtransaccion;

        if (parametros != null)
            objCmd.Parameters.AddRange(parametros);

        DbDataReader dbReader = objCmd.ExecuteReader();
        DataTable dt = new DataTable();
        dt.Load(dbReader);
        dbReader.Close();
        return dt;

任何帮助将不胜感激,

谢谢,

【问题讨论】:

  • 这可能是 ODBC(众所周知的慢)和自定义构建的 SQL Server 程序集(其中包含各种优化)之间的区别。无论如何,“编辑”部分之后的所有内容实际上都是一个答案。您应该将其移动到答案中,然后为了未来用户的利益而接受它(他们可能会跳过您的问题,因为它没有接受的答案)。

标签: asp.net sql-server performance ado.net oledbdataadapter


【解决方案1】:

我找到了解决办法!

是参数!

我在列表中使用了错误的类型!

Parametross.Add(bd.MakeParameter("@val", "%" + txtFind.Text + "%", DbType.String));

DbType.String 与 DbType.AnsiString

虽然 DbType.String 和 DbType.AnsiString 都处理字符数据,但这些数据类型的处理方式不同,使用错误的数据类型会对应用程序的性能产生负面影响。 DbType.String 将参数标识为 2 字节 Unicode 值,并按此方式发送到服务器。DbType.AnsiString 使参数作为多字节字符串发送。为避免过多的字符串转换,请使用:

  • DbType.AnsiString 用于 char 或 varchar 列和参数。
  • DbType.String 用于 unichar 和 univarchar 列和参数。

来源: http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc20066.0115/html/adonet/adonet49.htm

在我的查询中有一个:

.... 其中 Table.Col1 像 @val

但列类型是 varchar,我应该使用 DbType.AnsiString,而不是 DbType.String

Parametross.Add(bd.MakeParameter("@val", "%" + txtFind.Text + "%", DbType.AnsiString));

在我巨大的桌子上,我做了很多不必要的演员,这就是性能急剧下降的原因!

希望这会对某人有所帮助,

【讨论】:

    猜你喜欢
    • 2013-08-14
    • 1970-01-01
    • 2011-12-06
    • 2022-12-11
    • 2016-06-08
    • 1970-01-01
    • 2019-07-28
    • 2021-02-19
    • 1970-01-01
    相关资源
    最近更新 更多