我有2个表:tbl_Token(约1亿行)& tbl_EntryTokenSummary(约37.5亿行)
我试图理解为什么以下两种情况会导致不同的“网络”。计划。我不太明白为什么场景1甚至引用了非聚集索引,它不应该是相关的。
我认为可以说这是1418次扫描的结果,但为什么会这样做呢?
/********************************************************************
* Scenario 1
********************************************************************/
Select top 100
*
From (
Select
EntryId, FirstOccurence
From tbl_EntryTokenSummary
Where TokenId = (
Select Id
From tbl_Token
Where TSig = dbo.GetTokenSignature('water') and Text = 'water')
and EntryTypeId in (1,2)
) a
Inner Join (
Select
EntryId, FirstOccurence
From tbl_EntryTokenSummary
Where TokenId = (
Select Id
From tbl_Token
Where TSig = dbo.GetTokenSignature('pipe') and Text = 'pipe')
and EntryTypeId in (1,2)
) b on a.EntryId = b.EntryId
这会导致以下消息输出:
2018-04-18 22:15:40.5925859
(100 row(s) affected)
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tbl_EntryTokenSummary'. Scan count 1418, logical reads 20419, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tbl_Token'. Scan count 11, logical reads 21, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
2018-04-18 22:15:43.9677926
这个计划: QueryPlan Scenario 1
但是,如果我打破TokenId查找,结果会发生显着变化:
/********************************************************************
* Scenario 2
********************************************************************/
Declare @t1 int = (Select Id From tbl_Token Where TSig = dbo.GetTokenSignature('water') and Text = 'water')
print sysdatetime()
Declare @t2 int = (Select Id From tbl_Token Where TSig = dbo.GetTokenSignature('pipe') and Text = 'pipe')
print sysdatetime()
Select top 100
ets1.EntryId, ets1.FirstOccurence, ets2.EntryId, ets2.FirstOccurence
From tbl_EntryTokenSummary ets1
Inner Join tbl_EntryTokenSummary ets2 On ets2.TokenId = @t2 and ets1.EntryId = ets2.EntryId
Where ets1.TokenId = @t1
产生更好的输出:
2018-04-18 22:15:43.9677926
Table 'tbl_Token'. Scan count 6, logical reads 12, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
2018-04-18 22:15:43.9677926
Table 'tbl_Token'. Scan count 5, logical reads 9, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
2018-04-18 22:15:43.9677926
(100 row(s) affected)
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tbl_EntryTokenSummary'. Scan count 2, logical reads 1019, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
2018-04-18 22:15:44.1084285
编辑:
在查看表设置时,我意识到我没有设置主键,只有分区聚簇索引(实际上是唯一的,但没有标记为唯一)。
只是添加主键实际上使事情变得更糟,但是一旦我删除所有索引并添加回主键(作为分区/群集),查询优化器计算出更正确的计划就行了同样的事情。
原始查询计划:https://www.brentozar.com/pastetheplan/?id=Hku0KKH3f
更新了查询计划(在主键之后):https://www.brentozar.com/pastetheplan/?id=HJu3kwo2f
附注:我被引导到此链接作为生成的计划的解释: https://sqlperformance.com/2014/01/sql-plan/starjoininfo-in-execution-plans