【问题标题】:SQL Server Indexing OrderingSQL Server 索引排序
【发布时间】:2019-11-15 13:42:25
【问题描述】:

我有一张如下表

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 指定为要索引的第一列之外,有没有办法使索引成为搜索而不是扫描?

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

【问题讨论】:

  • 列顺序非常重要。 bertwagner.com/2018/09/04/…
  • 想象你有一个电话簿(如果你知道这样的事情),它以surname, first name 的顺序列出了每个人的名字。使用该书查找名字为John 的所有人。这本书使这项任务变得多么容易?

标签: sql sql-server indexing database-performance


【解决方案1】:

索引实际上创建了另一个版本的表,它只包含您提到的列。然后按照您指定的确切顺序对其进行排序(在您的示例中,它的顺序为 UserId->IssueId->CreatedDateTime)。由于索引中的 IssueId 列是第二个,这意味着如果这是您要搜索的主要值,则这些值将不按顺序排列。因此,SQL 必须对索引中的所有行执行“扫描”才能找到您正在搜索的项目。

如果您打算只搜索 IssueId,那么您需要调整您的索引。如果您计划有多个查询来搜索不同的值,那么您将需要不同的索引。

但请记住,向表添加索引会稍微减慢插入和更新速度,因为在提交更改之前需要同时更新索引。因此,您需要确保创建索引是因为您需要它,而不是“以防万一”。

【讨论】:

  • 是的,谢谢,所以我想知道我是否遗漏了任何东西,但似乎没有。是的,担心创建太多索引。为确认欢呼
【解决方案2】:

([UserId], [IssueId], [CreatedDateTime]) 上创建的索引仅在您的查询过滤时有用

  • 用户ID
  • 用户 ID、问题 ID
  • 用户 ID、创建日期时间
  • UserId、IssueId、CreatedDateTime

如果您只搜索UserId,则不应将其他fields 添加为key fields

您不能使用此索引搜索IssueIdCreatedDateTime,因为它们不是index最左键字段

在添加类似于您创建的index 之前,您应该三思而后行:您的index 具有原始table所有列,这意味着您只是复制了强>它。但是,如果您查看nonclustered indexsize,您会发现它比原来的table 大小甚至更大。小桌子可能没问题,但大桌子确实有问题。

如果您的大部分查询都在 UserId 上搜索,您可能会考虑重构您的 clustered index:它应该定义在用于大多数搜索的列上,而 PK 可以定义为 nonclustered

index 与您的 table 完全重复的另一个问题是,任何字段的任何更新都会导致您的 index 被更新,这会减慢您的数据修改速度。

【讨论】:

    猜你喜欢
    • 2011-09-06
    • 2016-10-12
    • 1970-01-01
    • 2010-09-25
    • 2011-03-18
    • 1970-01-01
    相关资源
    最近更新 更多