如何提高流程绩效?

时间:2012-10-03 08:50:59

标签: c# performance process

我有一个必须多次执行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 个答案:

答案 0 :(得分:2)

你正在同时启动600个进程,这对性能不利,它们可能需要大量内存,可能需要进行交换?

它也会在SQL服务器上产生大量负载,也可能是内存问题。

尝试按顺序运行查询,或者至少一次只运行几个查询。

修改
如旁注所示,您应该考虑使用SqlCommand而不是启动外部流程。

答案 1 :(得分:0)

如果每组文件只有一个数据库 - 你不应该登录每个文件/查询。

答案 2 :(得分:0)

我怀疑提高性能最有用的方法是将实际SQL命令的执行移动到应用程序中。

这可以避免

  • 创建多个进程(600,并行?!)
  • 重复连接(每个进程至少一个)
  • 次优锁争用(由于不确定的执行顺序)

我会将脚本存储为资源,然后在SqlConnection上执行。

考虑事务管理(如果适用)。处理此问题的最简单方法是仍然 打开 每个“脚本”的新连接。只要您每次使用相同的连接字符串执行此操作,框架就会自动将 连接起来。

答案 3 :(得分: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

此外,对于此任务,还有许多现有工具,谷歌用于“数据库部署工具”或其他一些工具。