1

最近、一連の複雑な C# ベースのスケジューリング ロジックを SQL CLR ストアド プロシージャ (SQL Server 2005 で実行) に変えました。次の理由から、コードが SQL CLR の優れた候補であると確信しました。

  • ロジックには、SQL Server からの大量のデータが含まれます。
  • ロジックが複雑で、TSQL を使用して実行するのが難しい
  • スレッド化や同期化、またはサンドボックスの外部からのリソースへのアクセスはありません。

私たちのSPの結果は、これまでのところかなり良いです. ただし、ロジックの出力は複数のデータ テーブルの形式であるため、sp の結果として単一の行セットを返すことはできません。代わりに、このコードでは、C# ジェネリック コレクションの各レコードを SQL テーブルに保存するために、foreach ループに多数の "INSERT INTO ...." ステートメントを使用しています。コード レビュー中に、SQL CLR 内のインライン SQL INSERT アプローチがパフォーマンスの問題を引き起こす可能性があるかどうかについて懸念を表明した人がいて、(C# ジェネリック コレクションから) データをダンプするための他のより良い方法があるかどうか疑問に思いました。

それで、何か提案はありますか?

4

2 に答える 2

2

数か月前に SQLite プロジェクトに取り組んでいるときにこれに出くわし、啓発的であることがわかりました。私はそれがあなたが探しているものかもしれないと思います。

...

標準の ADO.NET コンストラクトを使用してデータを挿入する最も高速なユニバーサルな方法

遅いものは片付けたので、ハードコアな一括読み込みについて話しましょう。SqlBulkCopy と、ISAM または他のプロバイダーのカスタム一括挿入クラスを含む特殊な構造を除けば、パラメーター化された INSERT ステートメントでの ExecuteNonQuery() の生の力に勝るものはありません。私はデモンストレーションします:

internal static void FastInsertMany(DbConnection cnn)
{

    using (DbTransaction dbTrans = cnn.BeginTransaction())
    {

        using (DbCommand cmd = cnn.CreateCommand())
        {

            cmd.CommandText = "INSERT INTO TestCase(MyValue) VALUES(?)";

            DbParameter Field1 = cmd.CreateParameter();

            cmd.Parameters.Add(Field1);

            for (int n = 0; n < 100000; n++)
            {

                Field1.Value = n + 100000;

                cmd.ExecuteNonQuery();

            }

        }

        dbTrans.Commit();

    }

}
于 2009-07-21T03:05:56.830 に答える
0

内部コレクションと同じ数の行で満たされた2列(COLLECTION_NAME nvarchar(max)、CONTENT xml)のテーブルを返すことができます。CONTENTは、コレクション内のデータのXML表現になります。

次に、SQL 2005/2008のXML機能を使用して、各コレクションのXMLをテーブルに解析し、テーブル全体に対してINSERTINTOまたはMERGEステートメントを実行できます。

これは、C#コード内の個々のINSERTよりも高速である必要があります。

于 2009-07-21T06:15:26.200 に答える