【问题标题】:Does using fully qualified names affect performance?使用完全限定名称会影响性能吗?
【发布时间】:2013-07-28 03:14:21
【问题描述】:

在 SQL Server 中使用完全限定的表名对性能有任何影响吗?

我有一个查询,我要连接不同数据库中的两个表。 DBA 建议在主机查询中省略数据库名称,我猜这是为了提高性能或约定。

所有表完全合格

USE [DBFoo]
SELECT * FROM [DBFoo].[dbo].[people] a
INNER JOIN [DBBar].[dbo].[passwords] b on b.[EntityID] = a.[EntityID]

首选?

USE [DBFoo]
SELECT * FROM [dbo].[people] a
INNER JOIN [DBBar].[dbo].[passwords] b on b.[EntityID] = a.[EntityID]

这真的有影响吗?

【问题讨论】:

  • 没有。使用“foo.dbo.people”与使用“people”相比,没有运行时性能提升。或相反亦然。书籍推荐:《Inside SQL Server》,Kalen Delaney 等人。

标签: sql sql-server tsql


【解决方案1】:

通常首选完全限定名称,但需要注意一些事项。我会说这在很大程度上取决于要求,一个答案可能无法满足所有情况。

请注意,这只是一个编译绑定,而不是执行绑定。因此,如果您执行相同的查询数千次,则只有第一次执行会“命中”查找时间,这意味着在完全限定名称的情况下查找时间会更短。这也意味着使用完全限定名称将节省编译开销(第一次执行查询时)。

其余的将重用已编译的,其中名称被解析为对象引用。

MSDN Article 提供了有关 SQL Server 最佳实践的公平指导。 (检查名为:如何引用对象的部分)

此链接更详细地解释了在执行前解决和验证对象引用的一系列步骤:http://blogs.msdn.com/b/mssqlisv/archive/2007/03/23/upgrading-to-sql-server-2005-and-default-schema-setting.aspx

通过第二个链接,结论说:

显然,最佳实践仍然有效:您应该完全限定所有对象名称,而根本不用担心名称解析成本。现实情况是,仍有许多不完善的应用程序,此设置非常适合这些情况。

此外,如果生产环境中不允许更改数据库名称,您可能会考虑在完全限定名称中包含数据库名称。

【讨论】:

  • 那是在谈论模式限定(两部分名称)而不是三部分名称。我肯定会避免在数据库对象(过程等)中使用三个部分名称,因为这意味着如果数据库被重命名或以新名称恢复,它们将需要更改。
  • @Martin:MSDN 文章说:要引用位于远程数据库中的对象,完全限定的对象名称包括服务器名称和数据库名称。这就是为什么 MSDN 文章被提到采取更多的想法。甚至 MSDN 的结论部分也证实了这一点:始终使用完全限定名称引用对象。至少,使用模式名称后跟对象名称。是的,数据库名称可以更改。然而,它更不可能发生在生产场景中。即使在测试场景 ( UAT ) 中也很少发生。
  • Msdn 还说:可以通过使用完全限定名称或 DEFAULT_SCHEMA 选项来改进评估过程。我会说这在很大程度上取决于要求,一个答案可能无法满足所有情况。数据库名称更改是可能的,但到目前为止,我认为这违反了许多组织遵循的标准做法。例如,由于我们通常在存储在 web.config 中的连接字符串中包含数据库名称。这肯定会影响部署到生产环境的所有应用程序。
  • @Martin:感谢朋友指出一个重点。我只是不想包含太多细节并造成混乱。所以我只是给出了文章的链接,以查看适合自己要求的每一个细节。刚刚在我的回答中添加了最后一行来说明这一点。
【解决方案2】:

在 SQL Server 中使用完全限定的表名对性能有影响吗?

由于查询文本较长,因此有更多字节要发送到 SQL Server 并进行解析,因此损失微乎其微。

惩罚是学术性的,诚实不会因为前缀而变得更好或更坏。

如果您观察到性能差异,可能是因为查询文本不同并且 SQL Server 生成了不同的计划。如果条件(统计信息,无论其他)在运行查询之间没有改变,那么 SQL Server 很可能会生成一个 100% 相同的计划。如果正在运行的带前缀和不带前缀查询之间的条件发生了变化,那么一个计划可能比另一个计划更好。

虽然在那种情况下,性能差异不是因为前缀。如果您从计划缓存中逐出计划并再次运行它们(从而使 SQL Server 有机会在相同条件下生成计划),您应该会看到两个查询具有相同的计划。

限定对象名称很重要(请参阅CREATE VIEW ... WITH SCHEMABINDING),但不会影响性能。

【讨论】:

    【解决方案3】:

    如果您迁移或重命名数据库名称,具有数据库前缀将导致问题。这可能是 DBA 建议这样做的原因

    【讨论】:

    • 如果[DBBar] 数据库名称发生变化,这仍然是一个问题。根据您的推理,这反过来又提出了一个奇怪的 DBA 建议。
    【解决方案4】:

    在 SQL Server 中使用完全限定的表名对性能有任何影响吗? 是的。重用计划缓存消除了“重新编译”计划的要求。

    顺便说一句:研究参数嗅探,因此计划重用不会对性能产生不利影响......另一方面。

    MSDN: 将新 SQL 语句与缓存中现有的、未使用的执行计划相匹配的算法要求所有对象引用都是完全限定的。例如,这些 SELECT 语句中的第一个与现有计划不匹配,第二个匹配:

    从人中选择 *;

    从 Person.Person 中选择 *;

    来源: https://technet.microsoft.com/en-us/library/ms181055(v=sql.105).aspx

    因此,MSDN 将 schema.name 视为完全限定的名称,它匹配。 不相信这与别名表的最佳实践相关,智能感知需要帮助......浑水。

    【讨论】:

      猜你喜欢
      • 2011-09-13
      • 1970-01-01
      • 2010-09-09
      • 2012-09-06
      • 2010-09-26
      • 2016-06-30
      • 2021-10-19
      • 1970-01-01
      • 2013-03-01
      相关资源
      最近更新 更多