簡體   English   中英

SQL 服務器索引訂購

[英]SQL Server Indexing Ordering

我有一張如下表

CREATE TABLE [dbo].[VideoRecipient](
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [UserId] [int] NOT NULL,
    [IssueId] [bigint] NOT NULL,
    [CreatedDateTime] [datetime2](7) NOT NULL,
    [NotifiedDateTime] [datetime2](7) NULL,
    [ReceivedDateTime] [datetime2](7) NULL,
    [ReadDateTime] [datetime2](7) NULL,
    [AcknowledgedDateTime] [datetime2](7) NULL,
    [IsDeleted] [bit] NOT NULL,
    [DeletedDateTime] [datetime2](7) NULL,
 CONSTRAINT [PK_VideoRecipient] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
))

然后我創建一個索引如下

CREATE NONCLUSTERED INDEX UX_VideoRecipient_UserId_IssueId_CreatedDateTime ON [dbo].VideoRecipient ([UserId], [IssueId], [CreatedDateTime]) INCLUDE ([ReadDateTime], [ReceivedDateTime], [AcknowledgedDateTime], [NotifiedDateTime])

當我通過UserId進行查詢以獲取記錄時,它使用索引並使用我想要的索引搜索。 如果我隨后進行查詢以通過IssueId獲取記錄,它會執行較慢的索引掃描。 除了創建另一個索引並將IssueId指定為要索引的第一列之外,有沒有辦法使索引成為搜索而不是掃描?

指定要索引的第一列似乎比我最初想象的更重要!

索引本質上創建了另一個版本的表,它只包含您提到的列。 然后按照您指定的確切順序對其進行排序(在您的示例中,它的順序為 UserId->IssueId->CreatedDateTime)。 由於索引中的 IssueId 列是第二個,這意味着如果這是您正在搜索的主要值,則這些值將不按順序排列。 因此,SQL 必須對索引中的所有行執行“掃描”才能找到您正在搜索的項目。

如果您打算只搜索 IssueId,那么您需要調整您的索引。 如果您計划有多個查詢來搜索不同的值,那么您將需要不同的索引。

但請記住,向表中添加索引會稍微減慢插入和更新速度,因為在提交更改之前需要同時更新索引。 因此,您需要確保創建索引是因為您需要它,而不是“以防萬一”。

([UserId], [IssueId], [CreatedDateTime])上創建的索引僅在您的查詢過濾時有用

  • 用戶身份
  • 用戶 ID、問題 ID
  • 用戶 ID、創建日期時間
  • 用戶 ID、問題 ID、創建日期時間

如果您只是在UserId上搜索,則不應將其他fields添加為key fields

您不能使用此索引來搜索IssueIdCreatedDateTime ,因為它們不是index最左鍵字段

在添加與您創建的index類似的索引之前,您應該三思而后行:您的index包含原始table所有列,這意味着您只是復制了它。 但是,如果您查看nonclustered indexsize ,您會發現它甚至比原始table的大小還要大。 對於小尺寸的桌子可能不是問題,但對於大桌子來說確實是一個問題。

如果您的大多數查詢都在UserId上搜索,您可能會考慮重構您的clustered index :它應該定義在用於大多數搜索的列上,並且 PK 可以定義為nonclustered

完全復制您的tableindex的另一個問題是,任何字段的任何更新都會導致您的index被更新,並且會減慢您的數據修改速度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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