Sql 查询联接和多个选择之间的大型表时,性能存在巨大差异

Sql 查询联接和多个选择之间的大型表时,性能存在巨大差异,sql,sql-server,Sql,Sql Server,我有一张有几十亿行的大桌子。以下语句返回相同的结果,但第一个语句(两步查询)耗时22秒,第二个语句(表联接)耗时3分钟 ColID是具有主键的标识列 基于colA和colB创建索引 从注释:上传查询计划上传的计划至少显示了问题,哈希连接。哈希表是根据ID(即聚集索引搜索)使用OptionArchive b返回的行创建的 您有选项类型和过期的索引吗?(您在问题的索引中只指定了2列),但查询选择了一个.mid_bid_ask,并加入了3列(strike、option_type、expiratio

我有一张有几十亿行的大桌子。以下语句返回相同的结果,但第一个语句(两步查询)耗时22秒,第二个语句(表联接)耗时3分钟

ColID是具有主键的标识列 基于colA和colB创建索引




从注释:上传查询计划上传的计划至少显示了问题,哈希连接。哈希表是根据ID(即聚集索引搜索)使用OptionArchive b返回的行创建的

您有选项类型和过期的索引吗?(您在问题的索引中只指定了2列),但查询选择了一个.mid_bid_ask,并加入了3列(strike、option_type、expiration),因此我怀疑它决定从seek“提示”到scan(从而从嵌套循环/索引seek+行ID查找)再到Hash+scan,以确保获得所需的领域

这可以作为一个相对容易的理论进行测试,包括在非聚集索引中的mid_bid_ask

question+schema信息中的查询与用于生成计划的查询不匹配是没有帮助的,尽管如此,我们仍然不知道正确的索引是什么

该计划本身(XML版本)正在向我们建议它认为需要的缺失索引:

 <MissingIndexes>
              <MissingIndexGroup Impact="99.0357">
                <MissingIndex Database="[Quotes]" Schema="[dbo]" Table="[OptionArchive]">
                  <ColumnGroup Usage="EQUALITY">
                    <Column Name="[expiration]" ColumnId="5"/>
                    <Column Name="[strike]" ColumnId="6"/>
                    <Column Name="[option_type]" ColumnId="7"/>
                  </ColumnGroup>
                  <ColumnGroup Usage="INCLUDE">
                    <Column Name="[mid_bid_ask]" ColumnId="27"/>
                  </ColumnGroup>
                </MissingIndex>
              </MissingIndexGroup>
            </MissingIndexes>


因此,这支持了覆盖索引的概念(包括mid\U bid\U ask),并且现有索引可能只覆盖3列中的2列。

我发现了问题。我创建的索引有4列,第一列根本不在查询中,因此不使用整个索引


我删除并重新创建了索引,删除了第一列,现在运行正常。

查询计划在这里可能会很有用:表定义包括索引?第二个问题是优化器正确估计将返回的行数的机会有限,它也无法优化对它们的搜索——它无法知道从带有
colID
1234
的行中获取的值恰好是选择性的。可能有一些方法可以解决这个问题,而不必求助于两个单独的查询,但是,是的,这里的查询计划会很有见地。上传查询计划:我猜你想要的结果是最快的,只有一个查询?什么查询计划?他粘贴了一个指向该计划的链接作为评论,我将编辑到问题中,但这与问题不同。不仅仅是名字不同。in子句不在问题中。@狗仔队-是的,同意,这是我在对far的回答中提到的一点,我认为NC索引在2列上,计划是在3列上确定一个缺少的索引。我不明白这一点:“因为它不知道它在OptionArchive a上加入了什么”,连接条件是这样的:在a.strike=b.strike和a.option\u type=b.option\u type和a.expiration=b.expiration上连接OptionArchive b
select top 1000 a.* 
from LargeTable a
     join LargeTable b on a.colA = b.colA
                      and a.colB = b.colB
where b.colID = 1234
 <MissingIndexes>
              <MissingIndexGroup Impact="99.0357">
                <MissingIndex Database="[Quotes]" Schema="[dbo]" Table="[OptionArchive]">
                  <ColumnGroup Usage="EQUALITY">
                    <Column Name="[expiration]" ColumnId="5"/>
                    <Column Name="[strike]" ColumnId="6"/>
                    <Column Name="[option_type]" ColumnId="7"/>
                  </ColumnGroup>
                  <ColumnGroup Usage="INCLUDE">
                    <Column Name="[mid_bid_ask]" ColumnId="27"/>
                  </ColumnGroup>
                </MissingIndex>
              </MissingIndexGroup>
            </MissingIndexes>