【问题标题】:MS SQL: Performance for querying ID descendingMS SQL:查询 ID 降序的性能
【发布时间】:2020-10-14 15:09:00
【问题描述】:

此问题与 Microsoft SQL Server 中的一个表有关,该表通常使用ORDER BY Id DESC 进行查询。

将主键设置为PRIMARY KEY CLUSTERED (Id DESC) 会带来性能优势吗?还是需要索引?还是没有它的情况下它的速度一样快?

表:

CREATE TABLE [dbo].[Items] (
    [Id] INT IDENTITY (1, 1) NOT NULL,
    [Category] INT NOT NULL,
    [Name] NVARCHAR(255) NULL,
    CONSTRAINT [PK_Items] PRIMARY KEY CLUSTERED ([Id] ASC)
)

查询:

SELECT TOP 1 * FROM [dbo].[Items]
WHERE Catgory = 123
ORDER BY [Id] DESC

【问题讨论】:

  • 一个主键就足够了。使主键降序 - 对于增加的主键 - 将对插入造成严重破坏。嗯,不完全是,但每次插入都需要大量数据移动。
  • 按 ID DESC 添加第二个索引不是更好吗?您可以尝试一些查询并检查执行计划。
  • 为什么在生产查询中有ORDER BY?使用ORDER BY 的理由并不像您想象的那么多! (并且索引或 PK 的排序对ORDER BY 的影响很小,因为在数据已经读入服务器的数据缓冲区之后评估ORDER BY:排序通常发生在内存中)。
  • “或者说它没有它的情况下也一样快?” - 我们需要查看您的完整查询 CREATE TABLE 定义(包括所有相关索引)和实际执行计划。其他一切都是猜测和推测。
  • @Dai 不过有一个很好的理由:可预测的排序。此外,如果查询分析器发现排序列在索引中,它可以简单地使用索引作为基础来选择行并完全放弃排序。

标签: sql sql-server sqlperformance sql-optimization


【解决方案1】:

将主键设置为 PRIMARY KEY 是否会带来性能优势 集群(Id DESC)?

如您所见:它取决于。

过滤器在 Category = 123 上。要查找 Category 123 的所有条目,因为没有定义任何 INDEX,服务器必须进行表扫描。除非你有一个非常大的结果集,和/或一些非常糟糕的配置 tempdb 和非常低的内存(因为磁盘仅在 tempdb 内存不足时使用),hte 结果的排序与表扫描相比是无关紧要的。

您实际上是在追随错误的尾巴。您更有可能通过向类别添加非唯一索引来加快查询速度,以便查询可以根据您的查询条件快速预过滤数据。

如果您要分析此查询的查询计划(您应该这样做 - 从技术上讲,如果您不付出一些努力,我们甚至不应该回答这个问题,并且查看查询计划就像您做的第一件事一样)您会非常可能会看到时间花在查询上,而不是结果排序上。

【讨论】:

  • 有时对于聚集表,需要分析整体使用情况和聚集在其他东西上,而不是盲目的升序主键,它可以由基本索引支持,通常由某种序列生成器支持为了独特性。如果 Category 非常结构化,它可能是聚集索引的一个很好的左元素,即使是单独的,也不是唯一的。插入增长会发生在类别的末尾,但如果类别不多,那也没什么大不了的!有些表几乎没有删除,所以漏洞可能也不是什么大问题!然后将一个类别的数据放在一起。
【解决方案2】:

根据以下没有区别

【讨论】:

    【解决方案3】:

    我建议在 (category, id desc) 上定义一个索引。 它将为您的查询提供最佳性能。

    【讨论】:

      【解决方案4】:

      正如其他人所指出的,类别索引(假设您没有)是这里可能的最大性能提升。

      但至于你的实际问题。对于像您这样的单个 order by 查询,就性能而言,查询/索引是按 desc 还是 asc 排序都没有关系。 SQL Server 可以轻松交换那些(从数据结构的开头或结尾开始)

      性能成为性能问题的地方是当您:

      1. 拥有多个order by
      2. 您的索引包含不止一列
      3. 您的order by 反对索引上的顺序。

      所以,假设您的主键有 ID asc 和 Category asc,然后您通过 ID asc 和 Category desc 进行查询。那么 SQL Server 就不能使用索引上的顺序来进行搜索了。

      有一些注意事项和陷阱。经过一番搜索,这个答案似乎列出了它们:

      SQL Server indexes - ascending or descending, what difference does it make?

      【讨论】:

        【解决方案5】:

        当只有一列时,按 asc 或 desc 顺序创建索引在“ORDER BY”中没有太大区别,但是当需要对两个不同方向的数据进行排序时,一列升序,另一列按降序排列的列创建索引的方式确实有很大的不同。

        看看这篇文章做了很多例子:

        https://www.mssqltips.com/sqlservertip/1337/building-sql-server-indexes-in-ascending-vs-descending-order/

        在您的场景中,我建议您在不包含“Id”的类别列上创建索引,因为聚集索引始终包含在非聚集索引中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-02-18
          • 1970-01-01
          • 1970-01-01
          • 2018-10-21
          • 2020-05-19
          • 2018-10-31
          • 2019-12-07
          相关资源
          最近更新 更多