我正在尝试删除索引扫描,但我似乎无法弄清楚如何使用我目前的理解来进行搜索。我看过整个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有条件地链接它们。动作。
目前的PK /指数:
CONSTRAINT [pk_UserDocuments] PRIMARY KEY CLUSTERED
(
[UserDocumentId] ASC
)
CREATE NONCLUSTERED INDEX [ix_ud_dtid] ON [dbo].[UserDocument]
(
[DocumentTypeId] ASC
)
DocumentTypeId是int not 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]
)
答案 0 :(得分:0)
我宁愿从dbo.Activity
表上的索引开始。现有的那些都不适合这个查询,但其中一个应该是诀窍:
(Action, ActionObjectId)
(Action, ActionObjectId) include (DateCreated)
(Action, ActionObjectId, DateCreated)
dbo.UserDocument
表上的索引就好了。
哦,是的,在排序时将datetime
列投射到date
是没有意义的。它不会给你任何有用的东西,但肯定会毁掉你可能拥有的索引的任何好处。