【问题标题】:Adding dummy where condition brings execution plan to seek在条件带来执行计划的地方添加虚拟对象
【发布时间】:2020-07-28 16:23:43
【问题描述】:

能否请您看一下http://sqlfiddle.com/#!18/7ad28/8 并帮助我理解为什么添加 where 条件会从扫描中获取索引?根据我的(错误)理解,它不应该有任何区别,因为它应该导致扫描的条件更大。

我还在下面粘贴有问题的表格脚本和查询


CREATE TABLE [dbo].[Mappings]
(
[MappingID] [smallint] NOT NULL IDENTITY(1, 1),
[ProductID] [smallint] NOT NULL,
[CategoryID] [smallint] NOT NULL
) 
GO
ALTER TABLE [dbo].[Mappings] ADD CONSTRAINT [pk_Mappings_MappingID] PRIMARY KEY CLUSTERED ([MappingID]) WITH (DATA_COMPRESSION = PAGE) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [nc_Mappings_ProductIDCategoryID] ON [dbo].[Mappings] ([ProductID], [CategoryID]) WITH (DATA_COMPRESSION = PAGE) ON [PRIMARY]
GO

CREATE TABLE [dbo].[CustomerProducts]
(
[CustomerID] [bigint] NOT NULL,
[ProductID] [smallint] NOT NULL,
[SomeDate] [datetimeoffset] (0) NULL,
[SomeAttribute] [bigint] NULL
) 
GO
ALTER TABLE [dbo].[CustomerProducts] ADD CONSTRAINT [pk_CustomerProducts_ProductIDCustomerID] PRIMARY KEY CLUSTERED ([ProductID], [CustomerID]) ON [PRIMARY]
GO

 
--SCAN [tempdb].[dbo].[Mappings].[nc_Mappings_ProductIDCategoryID].(NonClustered)   
SELECT b.[SomeDate],
       b.[SomeAttribute]
FROM dbo.[Mappings] a
    INNER JOIN dbo.CustomerProducts b
        ON a.[ProductID] = b.[ProductID]
Where b.CustomerID = 88;

--SEEK [tempdb].[dbo].[Mappings].[nc_Mappings_ProductIDCategoryID].(NonClustered)   
SELECT b.[SomeDate],
       b.[SomeAttribute]
FROM dbo.[Mappings] a
    INNER JOIN dbo.CustomerProducts b
        ON a.[ProductID] = b.[ProductID]
           AND b.CustomerID = 88
Where a.[ProductID] > 0;

【问题讨论】:

标签: sql sql-server tsql sql-server-2017


【解决方案1】:

“它不应该有任何区别,因为它应该导致扫描的条件更大。”

您添加了一个显式谓词 (ProductID > 0),因此 SQL Server 选择查找该值 (0),然后进行范围扫描。要查看此内容,请选择 Index Seek on Mappings,打开 Properties 选项卡,查找 Seek Predicates,然后展开整个结果树。您将在下方看到 Start 和适用的范围扫描属性。

因此,如果您有真实数据(假设您的 ProductID 为 1-100),并且 WHERE ProductID > 77。您将在 B-Tree 中查找 ProductID 77,然后 RANGE SCAN 剩余的非聚集索引。

观看:这将帮助您可视化和理解不同索引操作中内部发生的情况(免责声明:这是我介绍的) https://youtu.be/fDd4lw6DfqU?t=748

【讨论】:

    【解决方案2】:

    计划如下:

    以黄色悬停的是表CustomerProductsclustered index seek 的信息。搜索谓词设置为条件 [ProductID] > 0 的值,这是完全合理的,因为连接条件的一部分是 a.[ProductID] = b.[ProductID] 和 where 子句中的 a.[ProductID] > 0。这意味着 b.[ProductID] > 0。由于ProductID 是聚集索引上的第一列,因此可以使用任何减少查找的信息。 The seek operation should be faster than the scan,所以优化器会尝试这样做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多