【问题标题】:Performance differences between: JOIN within the same database, JOIN across two databases, JOIN of a database with a linked database (server object)性能差异:同一个数据库内的 JOIN、跨两个数据库的 JOIN、一个数据库与一个链接数据库(服务器对象)的 JOIN
【发布时间】:2013-10-04 23:50:31
【问题描述】:

这让我大吃一惊,我不能再测试三天,所以我不妨问问......

假设一个像这样的标准 JOIN 语句:

SELECT 
  names.name
  ,adresses.adress
FROM
  names
JOIN
  adresses
ON
  names.ID=adresses.FK_ID

假设您希望数据库引擎/优化器快速运行。

问题:有什么区别

  • 查询运行时间
  • 内存使用情况
  • 可用的 SQL Server 软件技术来提高运行时间

如果这些情况适用:

  1. 这两个表位于同一个数据库中
  2. 两张表位于同一实例的两个不同数据库中
  3. “names”表位于我的实例中,“adresses”表位于链接数据库(服务器对象)中

在案例 1 中,我增强此类查询运行时的常用策略(除了清除无效数据/重复项和根据需要减少数据类型长度)是构建适当的索引和统计信息。

如果我在案例 2 中这样做,优化器能否像案例 1 一样利用索引和统计信息?查询计划看起来是否相似?运行时间和内存使用是否相似? (我几乎 100% 肯定它会,也读过这个:What are the problems with a join between two tables in two different databases?

在情况 3 中,显然会涉及耗时的网络流量和协议内容/握手。我的实例是否会先将完整的“地址”结果集加载到 RAM/swap 中,然后再进行 JOIN?或者它是否足够聪明地告诉链接服务器:“嘿,查找这些 ID 并将结果地址还给我!” ? (假设链接数据库中的“地址”在 FK_ID 上有一个索引)

假设“地址”在 my 实例中,“名称”在链接实例中,我会添加

WHERE names.name='John Smith'

对于查询,我的实例是否会加载完整的“名称”集,然后在该堆中扫描匹配的 ID,然后在“地址”中进行索引查找?或者它是否能够询问链接的数据库:“你能为我找到这个名字的匹配 ID 吗?” (再次:假设存在一个关于 ID 的索引)然后用它转到它的“地址”?

基本上我想知道优化器到底有多聪明(我知道:它比我聪明^^)以及两个优化器是否可以以聪明的方式合作并提出一个融合的查询计划或其他东西,在至少在基本层面上。

这个问题可能已经被处理/回答/发布了很多次。感谢您的指针/链接/答案/技巧/解决方法...

【问题讨论】:

    标签: tsql sql-server-2008-r2


    【解决方案1】:

    简短的回答(鉴于您的问题很长,我对此感到有些内疚)是优化器非常了解服务器上的信息(因此案例 1 和案例 2 应该有相同的计划),但是对另一边的信息不太聪明。如果您对链接服务器(如 server.database.schema.table)执行 JOIN,您可能会以表扫描结束。

    【讨论】:

    • 关于这个问题没有太多炒作^^。谢谢你给我一些东西。既然你基本上证实了我已经猜到的:该死。所以复制是唯一真正的解决办法。
    • 我不敢说什么是“唯一真正的解决办法”;这一切都取决于。例如,您可以使用 OPENQUERY 来利用远程服务器上的索引,或者您可以重新设计您的架构,这样您就没有远程服务器了。
    • 感谢您的提示。我的目标是获得一个可以高频运行的运行时优化解决方案。 OPENQUERY 连接到远程源很有趣,需要测试它是否可以跨实例连接。然而,我认为这些函数的启动开销和仍然缺少的组合查询计划使所有这些都无法与复制竞争。链接服务器对业务至关重要,并且在速度足够快的机器上运行。它可以修改为分发器,但将其迁移到更快的位置并将其与其他实例融合被认为“不好笑”。这不是一家科技公司。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 2016-07-19
    相关资源
    最近更新 更多