具有聚集索引的原始广告订单

时间:2012-07-01 19:15:06

标签: sql indexing clustered-index

我对聚集索引有疑问。

在聚簇索引中,叶级节点本身按排序顺序保存数据,对吧?

也就是说,对于每次插入/更新/删除,对节点进行重新洗牌以维持排序顺序。

那么如何以插入的顺序从中检索数据呢?

想象一下,按照给定的顺序插入以下数据:1,7,4,5,2并在此字段上创建聚簇索引。

那么数据将按照1,2,4,5,7的顺序在内部存储吗?

因此,这可能有助于更快地查找特定值,但如果用户想要按照插入的顺序获得前3个值,该怎么办?

它们是否以某种方式可检索,或者我是否必须为插入的每一行分配增量ID,在其上声明非聚集索引,并根据对该id字段的记录进行排序来提供前3条记录的数据?

3 个答案:

答案 0 :(得分:2)

(基于SQL Server的答案 - 问题没有100%指定)

  

在聚簇索引中,叶级节点本身按排序顺序保存数据,对吧?

这不太正确,数据可以按叶片上的任何顺序存储,但页面上的插槽数组实际上是从页面读取数据的顺序 - 而不是数据的物理顺序。

  

也就是说,对于每次插入/更新/删除,对节点进行重新洗牌以维持排序顺序。

节点(例如页面被拆分,双链接列表上的前向/后向指针改变),但是在页面内,插槽阵列仍然是保留订单的实体,行本身不会被洗牌以匹配插槽数组顺序。

  

那么如何以插入的顺序从中检索数据呢?

通常不会保证它会按照确切的顺序 - 在堆页面上更容易发生,其中插槽阵列更能代表订单,但同样,不是保证。

  

想象一下,按照给定的顺序插入以下数据:1,7,4,5,2并在此字段上创建聚簇索引。那么数据将以1,2,4,5,7的顺序存储在内部吗?

不,它将被存储在页面上的1,7,4,5,2,但是插槽阵列将读取页面上的地址为7,5,4,2,1(它是从末尾构造的页面向后,所以你反向阅读。)

  

因此,这可能有助于更快地查找特定值,但如果用户想要按照插入的顺序获得前3个值,该怎么办?

在这种情况下有点无关紧要 - 除了没有关于排序的这样的保证之外,SQL会将整个页面读入内存。如果你想在这种级别上更多地了解SQL Internals,我仍然会推荐Kalen Delaneys SQL Internals书作为最好的资源之一。

如果您需要有关插入顺序的任何信息,我建议使用某种inserted_timestamp

答案 1 :(得分:1)

听起来你想在我的行上添加时间戳。我通常在我创建的所有表(用于审计)上放置以下列:

timecreated
timemodified
createdby
modifiedby
deleted

通过这些列,您可以通过将删除设置为true来告知您是谁创建了行以及何时,何时进行上次修改以及由谁以及可选地“软删除”该行。当然,系统中的所有其他查询都必须检查已删除的布尔值,以便软删除工作。

答案 2 :(得分:1)

表数据根据聚簇索引的顺序排序。 如果您想按照插入的顺序检查前3个值,则每个表上只能有一个聚簇索引,

  

USE AdventureWorks

     

     

创建表myTable99(
   Col1 int IDENTITY(1,1)PRIMARY KEY,Col2   Char(1),Col3 datetime DEFAULT getdate()

     

)GO

     

INSERT INTO myTable99(Col2)SELECT'A'UNION ALL SELECT'B'UNION ALL   选择'C'GO

     

SELECT * FROM myTable99   订购3   GO

     

DROP TABLE myTable99   GO

其他方法可能是:

  

CREATE TABLE CounterData]([CounterDataID] [bigint] IDENTITY(1,1)NOT   NULL,[DateTimeID] [bigint] NOT NULL,[Value] [float] NULL)ON   [PRIMARY]

     

创建独特的聚类索引[IX_DateTime_CounterDataID] ON   [PK]。[CounterData]

     

     

[DateTimeID] ASC,
  [CounterDataID] ASC

     

     

使用

     

(PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,SORT_IN_TEMPDB =   OFF,IGNORE_DUP_KEY = OFF,DROP_EXISTING = OFF,ONLINE = OFF,   ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON)ON [PRIMARY] GO