![](/img/trans.png)
[英]Conditional WHERE statement in SQL uses Index Scan instead of Index Seek
[英]SQL Server - index scan where index seek expected
我正在尝试删除索引扫描,但是根据目前的理解,我似乎无法弄清楚如何进行索引扫描。 我看过整个SO的其他文章,这些文章表明索引中列的顺序需要正确,并且就我目前的理解而言,它们似乎是正确的,但我可能会完全不赞成。 也许订单根本不是答案。
这是查询:
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
我认为值得一提的是Activity.ActionObjectId不是对UserDocument.UserDocumentId的外键引用-它是一个散列,用于存储其他主键值,然后根据Activity.Action有条件地链接到该主键值。
当前的PK /指数:
CONSTRAINT [pk_UserDocuments] PRIMARY KEY CLUSTERED
(
[UserDocumentId] ASC
)
CREATE NONCLUSTERED INDEX [ix_ud_dtid] ON [dbo].[UserDocument]
(
[DocumentTypeId] ASC
)
DocumentTypeId不为null。
查询计划最终产生:
内部联接哈希匹配也溢出到tempdb中。 不知道这是否有用。
将鼠标悬停在索引扫描上时,实际记录数为468,392。
有什么想法吗? 我会显示图片,但没有代表。 我很乐意以任何方式提供所需的更多信息。
编辑1:
表结构如下:
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
)
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]
)
我宁愿从dbo.Activity
表上的索引开始。 现有的查询都不适合该查询,但是其中之一应该可以解决问题:
(Action, ActionObjectId)
(Action, ActionObjectId) include (DateCreated)
(Action, ActionObjectId, DateCreated)
您在dbo.UserDocument
表上的索引就可以了。
哦,是的,在排序时将datetime
列转换为date
没有意义。 它不会给您任何有用的信息,但是肯定会破坏您可能拥有的索引的任何好处。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.