我有一张非常大的桌子,有数十亿行。以下语句返回相同的结果,但第一个(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
答案 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列。