2017-08-01 294 views
0

我知道表中的唯一一个聚集索引定义了行的物理排序方式,例如,在表中为什么主键应该是聚簇索引?

================================== 
      Contacts 
================================== 
ID (P.K.) | FirstName | LastName 
================================== 
    1  | 'Donald' | 'Trump' 
---------------------------------- 
    2  | 'Crooked' | 'Hillary' 
---------------------------------- 
    3  | 'Crazy' | 'Bernie' 

将意味着3条记录以上述顺序物理存储。但我不明白为什么这有帮助。也许在没有间隙的自动递增的主键的情况下,就像上面的例子中,这有助于为查询,如

SELECT FirstName+LastName FROM Contacts WHERE ID=2 

由于物理顺序使查找,如果ID=2O(1)时有发生(如得到一个索引数组的元素)。但是,如果表就像

================================== 
      Contacts 
================================== 
ID (P.K.) | FirstName | LastName 
================================== 
    1  | 'Donald' | 'Trump' 
---------------------------------- 
    89  | 'Crooked' | 'Hillary' 
---------------------------------- 
    12309 | 'Crazy' | 'Bernie' 

那么物理排序不允许O(1)查找;我们能做的最好的是O(log(n))

那么,为什么我们希望主键定义行的物理顺序呢?

+4

您并不总是希望聚簇索引是主键。这不是必需的,只有默认情况下,几乎总是最主要的关键也是聚集索引。 –

+2

我不确定在第一个示例或一般情况下,聚簇索引查找本身是“O(1)”。聚集索引只意味着一旦在索引中找到该项目,实际项目就在那里。在非聚集索引中,即使找到该项目,我们仍然需要在聚簇索引中进行查找以查找实际记录(如果我的术语稍微偏离,请原谅我)。 –

+0

不知道为什么这会得到downvoted或标记为不清楚。这是一个有效的问题,我很清楚OP在问什么。答案很长,因为它需要很多关于索引的信息,但问题本身对我来说似乎很合理。也许它之前已经被问过,但不值得赞扬。 –

回答

2

SQL Server中聚簇索引的重要性不是“物理排序”,而是行数据在B树的叶页中可用,因此避免了额外的查找。子树成本与非聚簇B树索引相同:O(log n)。

物理排序实际上是聚集索引内实际发生的内容的抽象。 extents内的页面存储在分配顺序中,不一定按聚簇索引键排序。索引键排序保持在索引分配映射表和指针链中,由此每个页面指向下一个(不一定相邻)页面。在页面内,行也按分配顺序写入和存储,而不是按键顺序,并且除非页面分割,否则顺序不会改变。当重建索引时,页面本身会使用,但重建之间不会自动维护顺序。

主键不一定是聚簇索引的最佳选择。这两个概念彼此正交。

相关问题