0

SQLスクリプトを何度も実行しなければならないメソッドがあります。これらのスクリプトは、データベース上にテーブル、ビュー、ストアドプロシージャ、および関数を作成するために使用されます。私は100個のファイルでうまく機能するこのコードを思いついた。

foreach (var folder in ActivityConstant.SourceFolders)
{
    var destination = context.GetValue(this.DestinationPath) + folder;

    // TODO: Execute all sql folders instead of each sql file.
    // this is cmd command for %f in (*.sql) do sqlcmd /S <servername> /d <dbname> /E /i "%f"

    foreach (var file in Directory.GetFiles(destination))
    {
        var begin = DateTime.Now;
        context.TrackBuildWarning(string.Format("Start exec sql file at {0}.", 
                                                DateTime.Now));

        Process process = new Process();
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.FileName = "sqlcmd.exe";
        process.StartInfo.Arguments = string.Format("-S {0} -d {1} -i {2} -U {3} -P {4}", 
                                                    sqlServerName, 
                                                    databaseName, 
                                                    file, 
                                                    sqlUserName, 
                                                    sqlPassword);
        process.StartInfo.WorkingDirectory = @"C:\";
        process.Start();
        //process.WaitForExit();

        context.TrackBuildWarning(
           string.Format(
                "Finished exec sql file at {0} total time {1} milliseconds.", 
                DateTime.Now, 
                DateTime.Now.Subtract(begin).TotalMilliseconds));
    }
}

今、私は次のステップに進んでいます。約600個のファイル(テーブル、ビュー、ストアドプロシージャ、関数)を含むデータベースでテストしていますが、現在のコードではこのような大量のクエリを処理できないようです。

私が記録を持っている限り、約100個のファイルを実行するのに3〜5分かかります。私がこの質問を書いているとき、それらの600個のファイルは40分でした。

コードを改善するにはどうすればよいですか。また、目標を達成するために異なる方法を使用する方がよい場合は、提案を歓迎します。

4

4 に答える 4

2

同時に 600 のプロセスを開始していますが、これはパフォーマンスに良くありません。おそらく大量の RAM を消費します。スワッピングが発生する可能性があります。

また、SQL サーバーに多くの負荷がかかり、メモリの問題になる可能性もあります。

クエリを順番に実行するか、一度に少なくとも数件だけ実行してみてください。

補足として、外部プロセスを起動する代わりに
使用を検討する必要があります。SqlCommand

于 2012-10-03T08:57:32.850 に答える
0

これが一連のファイルごとに 1 つのデータベースのみである場合は、すべてのファイル/クエリにログインするべきではありません。

于 2012-10-03T08:56:47.660 に答える
0

パフォーマンスを向上させる最も有効な方法は、実際の SQL コマンドの実行をアプリケーションに移すことだと思います。

これは回避します

  • 多くのプロセスを作成する (600、並行して ?!)
  • 繰り返し接続 (プロセスごとに少なくとも 1 つ)
  • 準最適なロック競合 (非決定的な実行順序による)

スクリプトをリソースとして保存してから、SqlConnection で実行する方法を検討します。

該当する場合は、トランザクション管理について考えてください。これを処理する最も簡単な方法は、「スクリプト」ごとに新しい接続を開くことです。 毎回同じ接続文字列を使用してこれを行う限り、接続はフレームワークによって自動的にプールされます。

于 2012-10-03T08:58:09.950 に答える
0

ファイルを実行する前に、ファイルのマージを試みることができます。

        using (var merged = File.OpenWrite("merged.sql"))
        {
            foreach (var file in Directory.GetFiles(destination))
            {
                var data = File.ReadAllBytes(file);
                merged.Write(data, 0, data.Length);
            }
        }
        //continue with "merged.sql" as source file for the sqlcmd

また、このタスクには多数の既存のツールがあり、Google で「データベース展開ツール」などを検索してください。

于 2012-10-03T09:01:35.093 に答える