【问题标题】:Smart choice for primary key and clustered index on a table in SQL 2005 to boost performance of selecting single record or multiple recordsSQL 2005 中表的主键和聚集索引的智能选择,以提高选择单条记录或多条记录的性能
【发布时间】:2010-10-06 00:22:27
【问题描述】:

编辑:我添加了“Slug”列来解决特定记录选择的性能问题。

我的表格中有以下列。

Id Int - Primary key (identity, clustered by default)
Slug varchar(100)
...
EntryDate DateTime

大多数时候,我是按 EntryDate 来订购 select 语句,如下所示。

Select T.Id, T.Slug, ..., T.EntryDate
From (
    Select Id, Slug, ..., EntryDate,  
        Row_Number() Over (Order By EntryDate Desc, Id Desc) AS RowNum
    From TableName
    Where ...
) As T
Where T.RowNum Between ... And ...

我按 EntryDate 和 Id 排序,以防有重复的 EntryDates。

当我选择 A 记录时,我会执行以下操作。

Select Id, Slug, ..., EntryDate
From TableName
Where Slug = @slug And Year(EntryDate) = @entryYear 
    And Month(EntryDate) = @entryMonth

我有一个独特的 Slug 和 EntryDate 键。

在我的情况下,什么是键和索引的明智选择?我面临性能问题可能是因为我按未聚集索引的列排序。

是否应该将 Id 设置为非聚集主键并将 EntryDate 设置为聚集索引?

感谢您的所有帮助。谢谢。

编辑:

我没有尝试在 EntryDate 上添加非聚集索引。从后端插入的数据,因此插入的性能对我来说没什么大不了的。此外,EntryDate 并不总是插入日期。它可以是过去的日期。后端用户选择日期。

【问题讨论】:

    标签: sql-server-2005 performance primary-key clustered-index


    【解决方案1】:

    根据当前表格布局,您需要一些这样的索引。

    CREATE INDEX IX_YourTable_1 ON dbo.YourTable
    (EntryDate, Id)
    INCLUDE (SLug)
    WITH (FILLFACTOR=90)
    
    CREATE INDEX IX_YourTable_2 ON dbo.YourTable
    (EntryDate, Slug)
    INCLUDE (Id)
    WITH (FILLFACTOR=80)
    

    将您要返回的任何其他列添加到 INCLUDE 行。

    将您的第二个查询更改为类似的内容。

    Select Id, Slug, ..., EntryDate
    From TableName
    Where Slug = @slug 
        AND EntryDate BETWEEN CAST(CAST(@EntryYear AS VARCHAR(4) + CAST(@EntryMonth AS VARCHAR(2)) + '01' AS DATE) AND DATEADD(mm, 1, CAST(CAST(@EntryYear AS VARCHAR(4) + CAST(@EntryMonth AS VARCHAR(2)) + '01' AS DATE))
    

    当前编写第二个查询的方式永远不会使用索引。如果您可以将 Slug 列更改为相关表,它将提高您的性能并降低您的存储需求。

    【讨论】:

      【解决方案2】:

      您是否尝试过在 entrydate 上简单地添加一个非聚集索引来查看您获得了什么样的性能提升?

      另外,多久添加一次新数据?添加的新数据是否总是 >= 最后一个 EntryDate?

      【讨论】:

      • 不,我没有尝试在 EntryDate 上添加非聚集索引。从后端插入的数据,因此插入的性能对我来说没什么大不了的。此外,EntryDate 并不总是插入日期。它可以是过去的日期。后端用户选择日期。
      【解决方案3】:

      您希望将 ID 保留为聚集索引,因为您很可能会从您的 id 而非输入日期加入到表中。

      只有日期字段的简单非聚集索引可以加快速度。

      【讨论】:

        【解决方案4】:

        集群有点像“索引分页”,索引是“分块”的,而不是简单的长列表。当您有大量数据时,这很有帮助。数据库可以在集群范围内搜索,然后找到单个记录。它使索引更小,因此搜索速度更快,但不太具体。一旦在集群中找到正确的位置,它就需要在集群中搜索。

        处理大量数据时速度更快,但处理较小数据集时速度较慢。

        如果您不使用主键进行大量搜索,则将日期聚类并保留主键非聚类。这实际上取决于您的查询与连接其他表的复杂程度。

        【讨论】:

        • 我在示例中添加了“Slug”列,以解决选择单个特定记录的性能问题。你能看看吗?谢谢。
        • 创建相关的 slugID、slugName 并使用 id 是个好主意。在文本字段中查找速度很慢。
        【解决方案5】:

        如果您要返回一堆记录,并且您返回的某些字段不是索引的一部分,则聚集索引只会产生任何影响。否则没有任何好处。

        您首先需要找出查询计划告诉您当前查询速度慢的原因。否则,它主要是无用的推测(这在优化查询时通常会适得其反。)

        如果没有可靠的查询计划来比较,我不会尝试任何事情(由我或其他人建议),至少知道你是在做善事还是在做坏事。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-17
          • 1970-01-01
          • 2012-04-25
          • 2011-01-24
          • 1970-01-01
          相关资源
          最近更新 更多