在连接和多个选择之间查询大表的巨大性能差异

时间:2018-03-20 14:41:17

标签: sql sql-server

我有一张非常大的桌子,有数十亿行。以下语句返回相同的结果,但第一个(2步查询)花了22秒,而第二个(表连接)花了3分钟。

ColID是具有主键的Identity列 基于colA和colB

创建索引
select @valA = colA, @valB = colB 
from LargeTable 
where colID = 1234

select top 1000 * 
from LargeTable
where colA = @valA
  and colB = @valB
select top 1000 a.* 
from LargeTable a
     join LargeTable b on a.colA = b.colA
                      and a.colB = b.colB
where b.colID = 1234

来自评论:上传查询计划https://www.brentozar.com/pastetheplan/?id=rJbHzoCKM

2 个答案:

答案 0 :(得分:1)

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

我删除并重新删除了第一列的索引,现在它正常工作。

答案 1 :(得分:0)

上传的计划至少会显示问题,哈希联接。正在使用OptionArchive b根据ID返回的行创建哈希表(这是聚簇索引查找)。

你有关于option_type和expiration的索引吗? (你在问题的索引中只指定了2列),但是查询是选择a.mid_bid_ask并且还连接3列(strike,option_type,expiration),所以我怀疑它已经决定从tip寻求扫描(从而从嵌套循环/索引搜索+行ID查找更改为哈希+扫描,以确保它获得所需的字段。

可以相对容易地将其作为理论进行测试,在非聚集索引中包含mid_bid_ask。

问题+架构信息中的查询与用于生成计划的查询不匹配没有帮助,但我们仍然不知道索引是否正确。

计划本身,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_bid_ask)的概念,并且现有索引可能只覆盖3列中的2列。