简体   繁体   English

SQL Server-在需要索引查找的位置进行索引扫描

[英]SQL Server - index scan where index seek expected

I'm attempting to remove an index scan, but I can't seem to figure out how to make it a seek with my current understanding. 我正在尝试删除索引扫描,但是根据目前的理解,我似乎无法弄清楚如何进行索引扫描。 I've looked at other posts throughout SO that suggest the ordering of the columns in the index need to be correct, and to my current understanding, they seem to be correct, but I could be completely off. 我看过整个SO的其他文章,这些文章表明索引中列的顺序需要正确,并且就我目前的理解而言,它们似乎是正确的,但我可能会完全不赞成。 And maybe the order isn't the answer at all. 也许订单根本不是答案。

Here is the query: 这是查询:

DECLARE @ChartActions TABLE
(
    InValue INTEGER
);
INSERT INTO @ChartActions
VALUES
(73),
(74),
(75);

with cteGroupedChartActivity AS (
    SELECT MAX(ActivityId) as ActivityId
    FROM Activity
    JOIN UserDocument  ON Activity.ActionObjectId = UserDocument.UserDocumentId
    WHERE   Action IN (SELECT * FROM @ChartActions)
    GROUP BY UserDocument.DocumentTypeId,CAST(Activity.DateCreated AS DATE)
)
select * from cteGroupedChartActivity

I believe it may be worth mentioning that Activity.ActionObjectId is not a foreign key reference to UserDocument.UserDocumentId--it is a loose column that we use to store other primary key values that we then link to conditionally based on Activity.Action. 我认为值得一提的是Activity.ActionObjectId不是对U​​serDocument.UserDocumentId的外键引用-它是一个散列,用于存储其他主键值,然后根据Activity.Action有条件地链接到该主键值。

Current PK/indices: 当前的PK /指数:

CONSTRAINT [pk_UserDocuments] PRIMARY KEY CLUSTERED 
(
    [UserDocumentId] ASC
)

CREATE NONCLUSTERED INDEX [ix_ud_dtid] ON [dbo].[UserDocument]
(
    [DocumentTypeId] ASC
)

DocumentTypeId is int not null. DocumentTypeId不为null。

The query plan ultimately yields: 查询计划最终产生:

  • Hash Match (Aggregate) 12% <= 哈希匹配(总计)12% <=
  • Hash Match (Inner Join) 57% <= 哈希匹配(内部联接)57% <=
  • Index Scan (NonClustered) [UserDocument].[ix_ud_dtid] 28% 索引扫描(非聚集)[UserDocument]。[ix_ud_dtid] 28%

The inner join hash match also spills over into tempdb. 内部联接哈希匹配也溢出到tempdb中。 Not sure if that's useful information or not. 不知道这是否有用。

When mousing over the index scan, the actual number of records is 468,392. 将鼠标悬停在索引扫描上时,实际记录数为468,392。

Any thoughts? 有什么想法吗? I'd show images but I don't have the rep. 我会显示图片,但没有代表。 I would be happy to provide any more info needed in any way that I can. 我很乐意以任何方式提供所需的更多信息。

Edit 1: 编辑1:

Table structures are as follows: 表结构如下:

CREATE TABLE [dbo].[Activity]
(
    [ActivityId] [int] IDENTITY(1,1) NOT NULL,
    [UID] [int] NULL,
    [Action] [int] NOT NULL,
    [ActionObjectId] [int] NOT NULL,
    [DateCreated] [datetime] NOT NULL,
    [PID] [int] NULL,
    [Data] [varchar](1024) NULL
)

CREATE TABLE [dbo].[UserDocument]
(
    [UserDocumentId] [int] IDENTITY(1,1) NOT NULL,
    [DocumentTypeId] [int] NOT NULL
)

Indices on dbo.Activity table: dbo.Activity表上的索引:

CONSTRAINT [pk_Activity] PRIMARY KEY CLUSTERED 
(
    [ActivityId] ASC
)

CREATE NONCLUSTERED INDEX [ix_a_a__inc__aoid_dc_pid] ON [dbo].[Activity]
(
    [Action] ASC
)
INCLUDE
(
    [ActionObjectId],
    [DateCreated],
    [PID]
)

CREATE NONCLUSTERED INDEX [ix_a_pid_uid_a_aoid_dc_d] ON [dbo].[Activity]
(
    [PID] ASC
)
INCLUDE
(
    [UID],
    [Action],
    [ActionObjectId],
    [DateCreated],
    [Data]
)

I would rather start with indices on dbo.Activity table. 我宁愿从dbo.Activity表上的索引开始。 None of the existing ones is suitable for this query, but one of these should to the trick: 现有的查询都不适合该查询,但是其中之一应该可以解决问题:

(Action, ActionObjectId)
(Action, ActionObjectId) include (DateCreated)
(Action, ActionObjectId, DateCreated)

Your indices on dbo.UserDocument table are just fine. 您在dbo.UserDocument表上的索引就可以了。

Oh, yes, and there is no sense in casting datetime column into date while sorting. 哦,是的,在排序时将datetime列转换为date没有意义。 It will not give you anything useful, but will definitely ruin any benefit from an index you may possibly have. 它不会给您任何有用的信息,但是肯定会破坏您可能拥有的索引的任何好处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM