簡體   English   中英

SQL Server-在需要索引查找的位置進行索引掃描

[英]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不是對U​​serDocument.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。

查詢計划最終產生:

  • 哈希匹配(總計)12% <=
  • 哈希匹配(內部聯接)57% <=
  • 索引掃描(非聚集)[UserDocument]。[ix_ud_dtid] 28%

內部聯接哈希匹配也溢出到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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM