我有一个必须多次执行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分钟了。
我想知道如何改进我的代码。我也欢迎任何建议,如果最好使用不同的方式来实现目标。
答案 0 :(得分:2)
你正在同时启动600个进程,这对性能不利,它们可能需要大量内存,可能需要进行交换?
它也会在SQL服务器上产生大量负载,也可能是内存问题。
尝试按顺序运行查询,或者至少一次只运行几个查询。
修改强>
如旁注所示,您应该考虑使用SqlCommand
而不是启动外部流程。
答案 1 :(得分:0)
如果每组文件只有一个数据库 - 你不应该登录每个文件/查询。
答案 2 :(得分:0)
我怀疑提高性能最有用的方法是将实际SQL命令的执行移动到应用程序中。
这可以避免
我会将脚本存储为资源,然后在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
此外,对于此任务,还有许多现有工具,谷歌用于“数据库部署工具”或其他一些工具。