使用 c# 提高 dacpac 部署的性能

Posted

技术标签:

【中文标题】使用 c# 提高 dacpac 部署的性能【英文标题】:Improve the performance of dacpac deployment using c# 【发布时间】:2017-04-12 09:23:02 【问题描述】:

我们正在部署到 MS SQL Server localdb 进行集成测试。

我们构建了一个数据库项目,并复制了生成的dacpac 文件以供 IntegrationTests 项目使用。到目前为止,我们有:

DatabaseProject.sqlproj
    bin/debug/DatabaseProject.dacpac
IntegrationTests.csproj 
    bin/debug/DatabaseProject.dacpac

我们在 IntegrationTests 项目中有一个程序集设置,其中创建了一个新的新数据库并将dacpac 部署到localdb。在 TearDown 中,数据库被删除,因此我们有一个确定的状态进行测试。

这是部署dacpac的代码,它使用DacServicesMicrosoft.SqlServer.DacSystem.Data.SqlLocalDbSystem.Data.SqlClient):

public void CreateAndInitializeFromDacpac(
ISqlLocalDbInstance localDbInstance,
string databaseName,
string connectionString,
string dacpacPath)


    using (var cx = localDbInstance.CreateConnection())
    
        cx.Open();
        using (var command = new SqlCommand(
            string.Format("CREATE DATABASE 0", databaseName), cx))
            command.ExecuteNonQuery();
    

    var svc = new DacServices(connectionString);

    svc.Deploy(
        DacPackage.Load(dacpacPath),
        databaseName,
        true
        );

我们现在有几个数据库项目,部署每个项目大约需要 8 秒。这会增加执行测试的总时间。

是否有可能以某种方式提高dacpac 的部署性能?

【问题讨论】:

Visual Studio 提供了跟踪哪些语句耗时的方法,尝试对其进行微调。如果无法对其进行微调,请尝试使用并行性来并行部署多个项目跨度> 您真的必须在单独的步骤中创建数据库吗?在没有测试自己的情况下,dacservices 可能会将 dacpac 中的所有对象与空数据库中的对应对象进行比较。 @GavinCampbell,TheGamesiwar,您的两个 cmets 都很有用,让我将 4 个数据库的总时间从 25 秒减少到 4.5 秒。 【参考方案1】:

加文是对的!

不要破坏数据库,而是使用 创建新数据库 选项,这样SSDT 在知道一个模型为空时不必浪费时间比较两个模型。

部署代码应改为:

var dacOptions = new DacDeployOptions  
               CreateNewDatabase = true
            ;

svc.Deploy(
    DacPackage.Load(dacpacPath),
    databaseName,
    true, 
    options: dacOptions
    );

如果你设置了这个标志,SSDT可以做很多额外的优化——如果你不喜欢使用反射器,看看Microsoft.Data.Tools.Schema.Sql.dllMicrosoft.Data.Tools.Schema.Sql.Deployment.SqlDeploymentPlanGenerator.OnInitialize(SqlDeployment)。如果设置了该标志,它将跳过整个连接到数据库并从部署的T-SQL 反向工程到模型。

这可能会导致一个潜在的错误,即人们更改模型数据库以包含一些对象,然后使用 SSDT 部署模型数据库中的对象,但随着边缘情况的发展,这听起来相当低!

按照 TheGameiswar 的建议,通过使用 Parallel.Foreach 并行化代码,还可以提高多数据库案例的性能。

【讨论】:

谢谢,埃德。我已经添加了所需的代码。正如我在上一条评论中添加的,我在初始化 4 个数据库时从 25s 下降到了 4.5s。 是的,我不确定 localdb 是否有任何“特殊考虑”会阻止这种方法起作用;显然没有! 次要注意:DacPackage 对象是一次性的。我建议处理它们。

以上是关于使用 c# 提高 dacpac 部署的性能的主要内容,如果未能解决你的问题,请参考以下文章

在 DACPAC 部署中使用 SQL 变量来区分权限

如何从 Azure DevOps DACPAC 部署中获取漂移报告?

Octopus - SQL 部署 DACPAC 社区贡献步骤

如何在没有实际部署的情况下测试 DACPAC 是不是可以部署

如何将 DACPAC 部署到事务复制数据库

由于缺少对象,DACPAC 无法部署