【问题标题】:Different ways to define which database to use?定义使用哪个数据库的不同方法?
【发布时间】:2017-08-07 09:44:52
【问题描述】:

我正在尝试找出您可以定义在 SSMS 中使用哪个数据库的方式的差异。

使用“可用数据库”下拉列表是否有任何功能差异

Adventure works Available Databases dropdown,

查询中定义的数据库

SELECT * FROM AdventureWorks2008.dbo.Customers

和 在开始时说明数据库?

USE AdventureWorks2008
GO
SELECT * FROM dbo.Customers

我很想知道每个案例在性能方面是否存在差异或在幕后发生的事情。

感谢您的帮助

【问题讨论】:

  • 在您提到的所有三种方法中从未发现任何性能差异

标签: sql-server database ssms


【解决方案1】:

是的,有。使用“USE AdventureWorks2008”时会增加非常小的开销,因为每次执行查询时它都会针对数据库执行它。它还将打印“命令已成功完成”。然而,它的开销是如此之小,如果你对这条消息没问题,那么就不要在意了。

【讨论】:

    【解决方案2】:

    是的,可能有区别。

    当您执行这样的语句时:SELECT * FROM AdventureWorks2008.dbo.Customers另一个 数据库(不是 AdventureWorks2008)的上下文中应用另一个数据库的设置。

    首先,任何数据库都有可能不同的Compatibility Level,因此它可以限制某些代码的使用,例如您不能在CL设置为80的数据库上下文中使用APPLY运算符,但您可以在数据库中使用 CL >= 90

    其次,每个数据库都有自己的一组选项,例如AUTO_UPDATE_STATISTICS_ASYNCForced Parameterization,它们会影响您的查询计划。 当数据库的上下文影响计划时,我确实遇到了一些情况:

    一种情况是当我为一个表创建过滤索引并在计划中使用它,直到我在具有简单参数化的数据库上下文中执行我的查询,并且在上下文中执行时它没有用于相同的查询具有强制参数化的数据库。当我使用提示强制该索引时,我得到了由于查询提示而无法生成查询计划的错误,所以我需要进行调查,我发现我的查询是参数化的,而不是我的条件fld = 0fld = @p,它不能使用我的过滤索引和fld = 0 条件。

    第二种情况是重新保护表基数估计:我们使用临时表在 ETL 过程中加载数据,然后切换到实际表,如下所示:

    insert into stg with(tablock);
     ...
    truncate table actual;
    alter table stg swith to actual;
    

    当程序编译时,所有临时表都是空的,但在 proc 中它们被数据填充,所以当我们在它们之间进行连接时,它们不再是空的。从 0 行传递到非 0 行会触发语句重新编译,它应该考虑实际行数,但它没有发生在生产服务器上,所以所有估计都是完全错误的(每个表 1 行),我需要调查.原因是在生产数据库中将AUTO_UPDATE_STATISTICS_ASYNC 设置为ON。 现在假设您有 2 个 db:db1 和 db2,此选项分别设置为 ON 和 OFF,在 db1 中此代码将有错误的估计,而如果您在 db2 中使用 db1.dbo.stg 执行它,它将有正确的估计。这两个数据库的执行时间会有很大的不同。

    【讨论】:

      猜你喜欢
      • 2018-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-16
      • 2017-09-11
      • 2018-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多