将索引扫描转换为索引查找

问题描述

我已向表添加索引以停止表扫描。现在它扫描的是索引而不是表,为什么不执行索引查找?

CREATE PROCEDURE [dbo].[GetPeople]
(
    @PlaceIDs [dbo].[Integers] READONLY,@RoleGroupIDs [dbo].[Integers] READONLY
)

AS
BEGIN
    SET NOCOUNT ON;
    SELECT
        PTS.PersonToSiteID,PTS.SiteID,PTS.PersonID,P.PersonID,P.Givenname,P.FamilyName,P.Email,P.LandlineNumber,P.MobileNumber,R.RoleTypeID
    FROM 
        [dbo].[PeopletoPlaces] PTS
        INNER JOIN (Select disTINCT Identifier FROM @PlaceIDs) Pl ON PTS.PlaceID = Pl.Identifier
        INNER JOIN [dbo].[People] P ON P.PeopleID = PTS.PeopleID 
        INNER JOIN [dbo].[Role] R ON R.RoleID = P.RoleID
        INNER JOIN (Select disTINCT Identifier FROM @RoleGroupIDs) RG ON R.RoleGroupID = RG.Identifier
END

我在 People 表上有一个覆盖索引,并在测试时添加distinct 子查询。有一个索引覆盖到 PTS 表的连接和标识符字段,因为 UDT 都是与它们连接的类型匹配的整数。与 JOIN 相比,我还尝试了 SELECT IN,但找不到避免索引扫描的方法

目前将此用作资源 - https://www.red-gate.com/simple-talk/sql/performance/identifying-and-solving-index-scan-problems/

解决方法

您的查询没有 WHERE 过滤子句;它要求该大连接的结果集中的所有记录。

如果您只想要结果集中的一行或很少的行,查询规划器会选择索引查找而不是索引扫描索引扫描是一个两步过程:首先它寻找它需要的第一行(可能是索引中的第一行)。然后依次扫描索引以获取所需的其余行。

扫描覆盖索引是获取多行结果集的有效方法:可以从索引中满足查询,因此查询计划器不必在索引和表数据本身之间来回切换。

这里一切都好。