为什么突破ID查找会导致不同的计划/性能

时间:2018-04-19 03:12:09

标签: sql sql-server sql-server-2014 query-planner

我有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

QueryPlan Scenario 2

编辑:

在查看表设置时,我意识到我没有设置主键,只有分区聚簇索引(实际上是唯一的,但没有标记为唯一)。

只是添加主键实际上使事情变得更糟,但是一旦我删除所有索引并添加回主键(作为分区/群集),查询优化器计算出更正确的计划就行了同样的事情。

原始查询计划: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

0 个答案:

没有答案