[英]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])
上創建的索引僅在您的查詢過濾時有用
如果您只是在UserId
上搜索,則不應將其他fields
添加為key fields
。
您不能使用此索引來搜索IssueId
或CreatedDateTime
,因為它們不是index
的最左鍵字段。
在添加與您創建的index
類似的索引之前,您應該三思而后行:您的index
包含原始table
的所有列,這意味着您只是復制了它。 但是,如果您查看nonclustered index
的size
,您會發現它甚至比原始table
的大小還要大。 對於小尺寸的桌子可能不是問題,但對於大桌子來說確實是一個問題。
如果您的大多數查詢都在UserId
上搜索,您可能會考慮重構您的clustered index
:它應該定義在用於大多數搜索的列上,並且 PK 可以定義為nonclustered
。
完全復制您的table
的index
的另一個問題是,任何字段的任何更新都會導致您的index
被更新,並且會減慢您的數據修改速度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.