[英]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.