【问题标题】:Merge Join over sorted columns instead of Hash Join在已排序的列上合并联接而不是哈希联接
【发布时间】:2021-01-01 04:37:02
【问题描述】:

我有两张桌子

A

(
    id int, 
    name varchar(39), 
    lname varchar (49), 
    ...
)

B

(
    id int, 
    city varchar(39), 
    ...
)

两个表都按列ID 排序。 ID 只是身份,由自动递增的整数 1 到 n 填充。

但是,如果我输入查询,例如,

SELECT * 
FROM A, B 
WHERE A.id = B.id;

我得到一个散列连接而不是高效的合并连接。如何改为在 SQL Server 中强制执行合并联接?我不想使用索引,因此没有基于索引的计划。

请注意,我也不希望使用 sort-enforcer 进行合并连接,我知道可以通过将查询重写为来提示规划器

SELECT * 
FROM A
INNER MERGE JOIN B ON A.ID = B.ID;

顺便说一句,我使用的是 SQL Server Express 版本。但是,如果后者支持我的目标查询计划,我可以更改为任何开源数据库。

提前致谢

【问题讨论】:

  • 为什么要使用古老的 ANSI-89 JOIN 语法?早就开始使用 ANSI-92 JOIN 语法了;它已经存在了大约 28 年。
  • @Larnu 所说的不仅是好建议,而且可能是您没有获得合并连接的原因:我认为合并连接不适用于完全连接,并且计划可能会在注意到之前将其丢弃“过滤条件”实际上是一个内部连接。
  • @Larnu 因为输入较少,如果连接语法影响优化器,那么 SQL 团队需要进行大量重新思考。但我不相信。
  • @GeorgeMenoutis 这不是真的,语法不会影响优化器。你可以试试看。如果真的发生了,那就奇怪了。你只能得到一个排序执行器的合并连接,这等于一个糟糕的计划!
  • “因为打字少”,我相信你在这里的意思是“懒惰”。这不是使用 28 年前被取代的语法的借口。停止使用它。

标签: sql-server


【解决方案1】:

如果您认为自己很聪明,那么 SQL 引擎 :-) 您可以使用这样的点击:

SELECT * 
FROM A
INNER HASH JOIN B
   ON A.id = B.id

SELECT * 
FROM A
INNER MERGE JOIN B
   ON A.id = B.id

至少,您可以测试MERGE 是否真的会更好。即使在这种情况下更好,也不意味着它将永远是最佳选择。它在其他情况下会降低性能,因此通常将这项工作留给引擎会更好。

【讨论】:

  • 感谢您的回答,但它不起作用,计划者正在引入排序执行器,但这不是必需的,因为数据已经排序。
  • @Тrex 你有例如每张桌子上的 PK 吗?
  • 如果我在有问题的列上定义 PK,那么系统将创建一个聚集索引,这就是我想要避免的。我的目标是对两个关系进行合并连接,而不是索引扫描计划。但我明白你的意思。
  • @Trex PK 可以定义为非集群的。关键是 - 你相信数据是有序的,但如果没有辅助结构(索引)来帮助引擎以有序的方式提取它,你就无法避免排序阶段。
  • 感谢您的回答,但是我希望找到某种选项,您可以在其中进行设置,以保证排序,从而完全避免使用索引。
猜你喜欢
  • 2011-05-07
  • 2016-09-05
  • 1970-01-01
  • 1970-01-01
  • 2018-10-05
  • 2018-06-17
  • 2012-09-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多