1

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 @ = "select *
from Table1 where Name like @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;

2013年1月14日編集(18:44)

SqlConnectionとSqlCommandを直接使用しているので、DbProviderFactoryから接続を取得しなくなりました。DbCommandとDbProviderが基本クラスであることは知っていますが、パフォーマンスが300%のように大幅に向上するため、そこにはもっと何かがあると思います。

前に示したコードですでに試したので、これはfillメソッドではありません。

とにかく、理由はわかりませんが、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;

どんな助けでも大歓迎です、

ありがとう、

4

1 に答える 1

8

私は解決策を見つけました!

パラメータでした!

リストで間違ったタイプを使用していました!

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

DbType.StringとDbType.AnsiString

DbType.StringとDbType.AnsiStringはどちらも文字データを処理しますが、これらのデータ型は異なる方法で処理され、間違ったデータ型を使用すると、アプリケーションのパフォーマンスに悪影響を与える可能性があります。DbType.Stringは、パラメーターを2バイトのUnicode値として識別し、そのようにサーバーに送信されます。DbType.AnsiStringにより、パラメーターはマルチバイト文字列として送信されます。過度の文字列変換を回避するには、次を使用します。

  • charまたはvarchar列およびパラメーター のDbType.AnsiString 。
  • unicharおよびunivarcharの列とパラメーターのDbType.String。

出典: http://infocenter.sybase.com/help/index.jsp?topic = / com.sybase.infocenter.dc20066.0115 / html / adone / adonet49.htm

私のクエリには次のものがあります。

....ここでTable.Col1は@valのように

ただし、列タイプはvarcharであり、DbType.Stringの代わりにDbType.AnsiStringを使用する必要があります

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

私の巨大なテーブルでは、不必要なキャストをたくさん作っていました。これがパフォーマンスが大幅に低下する理由です。

これが誰かを助けることを願っています、

于 2013-01-15T01:10:06.640 に答える