Sql server 如果字段索引是常量,联接能否有效地忽略它们?

Sql server 如果字段索引是常量,联接能否有效地忽略它们?,sql-server,performance,tsql,Sql Server,Performance,Tsql,用一个例子来解释这一点要容易得多 表A上有PK(商店、生产线)。 表B上有PK(id、门店、行)。 在这两种情况下,[id]是int,[store]是nvarchar(100),而[line]是int 如果我跑步: select * from A inner join B on A.store=B.store and A.line=B.line where B.id=0 引擎是否能够快速(我正在考虑合并)加入?或者在语句中添加一个值为0的伪列id会有帮助吗?您的语句会起作用,但如果您这样做

用一个例子来解释这一点要容易得多

表A上有PK(商店、生产线)。
表B上有PK(id、门店、行)。
在这两种情况下,[id]是int,[store]是nvarchar(100),而[line]是int

如果我跑步:

select * 
from A inner join B 
on A.store=B.store and A.line=B.line
where B.id=0

引擎是否能够快速(我正在考虑合并)加入?或者在语句中添加一个值为0的伪列
id
会有帮助吗?

您的语句会起作用,但如果您这样做,优化器会更有效:

select * 
from A inner
join B on A.store=B.store and A.line=B.line and B.id=0
在合并之前,这里可以排除b.id不等于零的项。根据表大小、拓扑结构等,这可能非常重要

例如,考虑在5个节点表B和1个表A中共享5000万行的情况——在您的代码中,所有记录都必须被移动到具有A表的节点,而上面的代码只需要具有ID=0的记录。


当一个表是一个小表(通常只在一个节点上)时,这可能非常不直观。

您的语句会起作用,但如果您这样做,优化器将更有效:

select * 
from A inner
join B on A.store=B.store and A.line=B.line and B.id=0
在合并之前,这里可以排除b.id不等于零的项。根据表大小、拓扑结构等,这可能非常重要

例如,考虑在5个节点表B和1个表A中共享5000万行的情况——在您的代码中,所有记录都必须被移动到具有A表的节点,而上面的代码只需要具有ID=0的记录。


当a是一个小表(通常仅在一个节点上)时,这可能非常不直观。

无论条件在何处,当使用内部联接时,我不理解@DenisRubashkinI意味着优化器将为这两种情况生成相同的查询计划,要么
B.id=0
在where子句中,要么在join@DenisRubashkin---我知道并非所有平台都是如此。我最近没有专门与SQL server合作处理过这样的案例,我现在没有访问权限,但是当我们移动到云时,我们可以假设数据是分片的,正如我上面描述的那样。这也是一个简单的例子——优化器可以看到这里没有差别,但是考虑到有更多的连接和子查询的情况,那么优化器就必须尊重逻辑上的差异。@ DenisRubashkin,你可能把这个问题与在WHERE子句中发生的另一个问题混淆起来。您有一个左连接,并通过引用中的值将其转换为内部连接,从而将其转换为内部连接。您是对的——这与那个不同,但它很相似——它确实从根本上改变了从联接表检索数据时访问数据的方式。与left join不同,它不会改变结果,但会对性能产生重大影响,当使用内部联接时,我不理解@DenisRubashkinI意味着优化器将为这两种情况生成相同的查询计划,要么
B.id=0
在where子句中,要么在join@DenisRubashkin---我知道并非所有平台都是如此。我最近没有专门与SQL server合作处理过这样的案例,我现在没有访问权限,但是当我们移动到云时,我们可以假设数据是分片的,正如我上面描述的那样。这也是一个简单的例子——优化器可以看到这里没有差别,但是考虑到有更多的连接和子查询的情况,那么优化器就必须尊重逻辑上的差异。@ DenisRubashkin,你可能把这个问题与在WHERE子句中发生的另一个问题混淆起来。您有一个左连接,并通过引用中的值将其转换为内部连接,从而将其转换为内部连接。您是对的——这与那个不同,但它很相似——它确实从根本上改变了从联接表检索数据时访问数据的方式。与left join的情况不同,它不会改变结果,但会对性能产生重大影响。只需检查一下……@Pankaj_Dwivedi——这与此问题无关。实际执行计划将显示优化器选择的内容。没有理由在
a
中添加列。您可以简单地将
id
条件添加到
on
子句中,而不是使用
where
子句。为什么不自己测试呢?讨论假设的性能问题没有意义。任何性能问题的答案都是“视情况而定”。因为它取决于实际的查询、所涉及对象的DDL、连接列中值的分布、统计信息等,正如MJH已经建议的那样,只需自己测试一下。只需检查一下……@Pankaj_Dwivedi——这与此问题无关。实际执行计划将显示优化器选择的内容。没有理由在
a
中添加列。您可以简单地将
id
条件添加到
on
子句中,而不是使用
where
子句。为什么不自己测试呢?讨论假设的性能问题没有意义。任何性能问题的答案都是“视情况而定”。因为它取决于实际的查询、所涉及对象的DDL、连接列中值的分布、统计信息等,正如MJH已经建议的那样,只需自己测试它。