【问题标题】:"Clustered index" and "Order by Clause"“聚集索引”和“按子句排序”
【发布时间】:2011-06-01 05:30:41
【问题描述】:

Clustered IndexOrder by Clause有什么区别吗?

我必须从主表中填充下拉列表,然后是查询。

Select Id, Name from Table Order by Name

我应该使用 Order by Clause 还是 Clustered Index 来完成上述任务?

编辑

下面是表的架构

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[lookup]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[lookup](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NULL,
 CONSTRAINT [PK_lookup_ID] PRIMARY KEY NONCLUSTERED
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
END
GO

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[lookup]') AND name = N'IX_lookup_Name')
CREATE CLUSTERED INDEX [IX_lookup_Name] ON [dbo].[lookup]
(
    [Name] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]

我在Name 上也有一个聚集索引。但现在它没有显示在模式中。抱歉,我不知道为什么。

【问题讨论】:

  • 我猜,您应该按任何要求(ID 或名称)订购。对我来说,名称看起来像是正确的订单字段。

标签: sql-server sql-server-2005 sql-server-2008


【解决方案1】:

苹果和橙子。聚集索引是一种存储选项。 ORDER BY 是一个查询选项。如果您需要有序结果,获取它们的唯一方法是在查询中添加 ORDER BY 子句。时期。

索引可以帮助查询优化器生成更有效的计划,并利用索引作为满足 ORDER BY 要求的手段。但是,无论是集群的还是非集群的,索引的存在都不能保证结果的任何顺序。

因此,您在查询中绝对需要 ORDER BY。您还可以考虑使用Name 列的索引来帮助查询。是否使用索引取决于更多因素。你应该阅读Designing IndexesThe Tipping Point

【讨论】:

【解决方案2】:

索引允许快速搜索过滤“WHERE CLAUSE”,但还具有额外的好处,即数据将被排序。

例子

这就是数据在表格中的保存方式。

ID    Name
1     Jack
2     Bob
3     Jill

如果您在 Name(ASC) 上添加聚集索引,这就是它的保存方式(主键始终与每个索引一起存储以供查找信息)

2     Bob
1     Jack
3     Jill

所以使用你的 SQL

Select Id, Name from Table Order by Name

对于没有聚集索引的选择,数据库将检查是否存在有助于更快完成工作的索引。它不会找到任何数据,因此它将从表中选择数据,对其进行排序,然后返回。

对于使用聚集索引进行选择,数据库将检查是否存在有助于更快完成工作的索引。它将找到按 ASC 排序的名称索引。它可以只从索引中选择ID和Name,然后返回它知道数据已经排序。

因此,如果没有名称索引,数据库必须在每次运行查询时对数据进行排序。 使用索引,在插入或更新数据时进行排序(这会稍微减慢更新速度),不同之处在于它只需要排序一次,而不是每次。

【讨论】:

  • 有什么类似的,不使用 order by,我们只有聚集索引来对数据进行排序。系统不保证排序?
  • 我不确定你到底在问什么。如果您只有一个聚集索引并且没有排序依据,那将留下主键和聚集索引。由于聚集索引不会给查询带来任何好处,我假设将使用对表的扫描并且忽略聚集索引,这将导致选择不会被排序。我不确定为什么您不希望在查询中按顺序排列,但仍希望对结果进行排序。您也许可以强制查询使用聚集索引,但这不是最好的处理方式。
【解决方案3】:

如果 Id 是您的主键(这是常见的场景)并且用于连接,您应该在 Id 上创建聚集索引。 但是为了提高搜索性能,您应该在 Name 上创建包含 Id 的非聚集索引。

【讨论】:

  • 我选择了没有 where 子句的 Id 和 Name
【解决方案4】:

聚集索引和 order by 子句是两个完全不同的东西。聚集索引决定存储表中的行如何排序。 order by 子句决定查询结果的排序方式。

非聚集索引在数据库存储中创建另一个“影子表”,该表按索引列排序。它还包含主键,以便它可以在“真实”表中快速找到正确的行。数据库设计的最佳实践是在主键上创建聚集索引(除非有反对的理由)。任何其他需要索引的列都可以在非聚集索引中处理。

为了优化性能,where 子句条件可以使用索引比 order by 可以更重要。

【讨论】:

    【解决方案5】:

    我的第一个问题是:什么是业务用例?如果答案是“按名称顺序显示行”,则按名称排序。

    既然你提到你已经在 Name 上有一个非聚集索引,你应该很高兴。

    我还认为您无论如何都会过滤“名称”​​上的数据,所以您已经在使用索引了。

    我的第二个想法:你是否过早地优化了这个?该表将有数千或数百万行吗?如果没有,您可能不会注意到索引是否存在。如果您确实有数千行,那么在不过滤的情况下下拉框的表现如何?

    我们可以进行大量猜测,因此最好在您的环境中分析查询。

    一般来说,如果数据是相对静态的,您可以将 CLUSTERED INDEX 放在递增值(IDENTITY、创建日期等)上。并非每个表都需要聚集索引。

    【讨论】:

    • 对于数百万条记录,聚集索引是否提供了明显的性能差异?
    猜你喜欢
    • 2021-11-24
    • 2019-02-13
    • 1970-01-01
    • 2011-03-25
    • 2019-09-27
    • 2013-08-07
    • 2021-01-14
    • 2021-09-07
    相关资源
    最近更新 更多