使用参数执行查询时,SqlCommand会变慢

时间:2013-01-14 13:13:53

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

执行参数时,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正在执行一个非常糟糕的执行计划。

由于这个错误的选择,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;

非常感谢任何帮助,

谢谢,

1 个答案:

答案 0 :(得分:5)

我找到了解决方案!

这是参数!

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

  

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));

在我庞大的牌桌上,我制作了许多不必要的演员表,这就是为什么表演大幅下降的原因!

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