我对DB的接触有限,只是作为应用程序程序员使用过DB。我想知道关于聚集和非聚集索引。 我在谷歌上搜索了一下,我发现:

A clustered index is a special type of index that reorders the way records in the table are physically stored. Therefore table can have only one clustered index. The leaf nodes of a clustered index contain the data pages. A nonclustered index is a special type of index in which the logical order of the index does not match the physical stored order of the rows on disk. The leaf node of a nonclustered index does not consist of the data pages. Instead, the leaf nodes contain index rows.

我在SO中发现的是聚集索引和非聚集索引之间的区别是什么?

有人能用通俗易懂的语言解释一下吗?


当前回答

使用聚集索引,行按与索引相同的顺序物理存储在磁盘上。因此,只能有一个聚集索引。

对于非聚集索引,有第二个列表,其中包含指向物理行的指针。您可以有许多非聚集索引,尽管每个新索引都会增加写入新记录的时间。

如果想要返回所有列,从聚集索引中读取通常更快。您不必先访问索引,再访问表。

如果需要重新排列数据,则写入具有聚集索引的表可能会较慢。

其他回答

聚集索引: 如果表上不存在聚集索引,主键约束将自动创建聚集索引。聚类索引的实际数据可以存储在索引的叶级。

Non Clustered Index: Actual data of non clustered index is not directly found at leaf node, instead it has to take an additional step to find because it has only values of row locators pointing towards actual data. Non clustered Index can't be sorted as clustered index. There can be multiple non clustered indexes per table, actually it depends on the sql server version we are using. Basically Sql server 2005 allows 249 Non Clustered Indexes and for above versions like 2008, 2016 it allows 999 Non Clustered Indexes per table.

聚集索引——聚集索引定义了数据在表中物理存储的顺序。表数据只能按某种方式排序,因此,每个表只能有一个聚集索引。在SQL Server中,主键约束自动在特定列上创建聚集索引。

Non-Clustered Index - A non-clustered index doesn’t sort the physical data inside the table. In fact, a non-clustered index is stored at one place and table data is stored in another place. This is similar to a textbook where the book content is located in one place and the index is located in another. This allows for more than one non-clustered index per table.It is important to mention here that inside the table the data will be sorted by a clustered index. However, inside the non-clustered index data is stored in the specified order. The index contains column values on which the index is created and the address of the record that the column value belongs to.When a query is issued against a column on which the index is created, the database will first go to the index and look for the address of the corresponding row in the table. It will then go to that row address and fetch other column values. It is due to this additional step that non-clustered indexes are slower than clustered indexes

聚类索引和非聚类索引的区别

每个表只能有一个聚集索引。但是,你可以 在一个表上创建多个非聚集索引。 聚集索引只对表进行排序。因此,他们不消费 额外的存储。非聚集索引存储在单独的位置 从实际表中占用更多的存储空间。 聚集索引比非聚集索引快,因为它们 不要涉及任何额外的查找步骤。

有关更多信息,请参阅本文。

聚集索引

聚类索引决定了表中DATA的物理顺序。因此,一个表只有一个聚集索引(主键/组合键)。

“字典”不需要任何其他索引,它已经根据单词索引

非聚集索引

非聚集索引类似于Book中的索引。数据存储在一个地方。索引存储在另一个位置,并且索引具有指向存储位置的指针。这有助于快速搜索数据。因此,一个表有超过1个非聚集索引。

“生物书”在开头有一个单独的索引指向章节的位置,在“结尾”有另一个索引指向常用单词的位置

聚集索引

聚集索引根据表或视图中的键值对数据行进行排序和存储。这些是包含在索引定义中的列。每个表只能有一个聚集索引,因为数据行本身只能按一种顺序排序。

只有当表中包含聚集索引时,表中的数据行才会按排序顺序存储。当一个表具有聚集索引时,这个表称为聚集表。如果表没有聚集索引,则其数据行存储在称为堆的无序结构中。

非聚集

Nonclustered indexes have a structure separate from the data rows. A nonclustered index contains the nonclustered index key values and each key value entry has a pointer to the data row that contains the key value. The pointer from an index row in a nonclustered index to a data row is called a row locator. The structure of the row locator depends on whether the data pages are stored in a heap or a clustered table. For a heap, a row locator is a pointer to the row. For a clustered table, the row locator is the clustered index key.

可以将非键列添加到非聚集索引的叶级,以绕过现有的索引键限制,并执行完全覆盖的索引查询。有关更多信息,请参见创建包含列的索引。有关索引键限制的详细信息,请参见SQL Server最大容量规格。

参考:https://learn.microsoft.com/en-us/sql/relational-databases/indexes/clustered-and-nonclustered-indexes-described

聚集索引

聚集索引基本上是一个树状组织的表。与将记录存储在未排序的Heap表空间中不同,聚集索引实际上是具有叶子节点(按群集键列值排序)的B+树索引,存储实际的表记录,如下图所示。

在SQL Server和MySQL中,Clustered Index是默认的表结构。即使表没有主键,MySQL也会添加一个隐藏的集群索引,而SQL Server总是在表有主键列时构建一个集群索引。否则,SQL Server将存储为堆表。

聚集索引可以加速按聚集索引键过滤记录的查询,就像通常的CRUD语句一样。由于记录位于叶节点中,因此在根据记录的Primary Key值定位记录时,不需要额外查找额外的列值。

例如,在SQL Server上执行如下SQL查询:

SELECT PostId, Title
FROM Post
WHERE PostId = ? 

您可以看到,执行计划使用群集索引查找操作来定位包含Post记录的叶子节点,并且扫描群集索引节点只需要两个逻辑读取:

|StmtText                                                                             |
|-------------------------------------------------------------------------------------|
|SELECT PostId, Title FROM Post WHERE PostId = @P0                                    |
|  |--Clustered Index Seek(OBJECT:([high_performance_sql].[dbo].[Post].[PK_Post_Id]), |
|     SEEK:([high_performance_sql].[dbo].[Post].[PostID]=[@P0]) ORDERED FORWARD)      | 

Table 'Post'. Scan count 0, logical reads 2, physical reads 0

非聚簇索引

由于聚集索引通常是使用主键列值构建的,如果您想加快使用其他列的查询速度,那么必须添加次要非聚集索引。

二级索引将在它的叶节点中存储主键值,如下图所示:

因此,如果我们在Post表的Title列上创建一个Secondary Index:

CREATE INDEX IDX_Post_Title on Post (Title)

然后执行下面的SQL查询:

SELECT PostId, Title
FROM Post
WHERE Title = ? 

我们可以看到,索引查找操作用于在IDX_Post_Title索引中定位叶子节点,它可以提供我们感兴趣的SQL查询投影:

|StmtText                                                                      |
|------------------------------------------------------------------------------|
|SELECT PostId, Title FROM Post WHERE Title = @P0                              |
|  |--Index Seek(OBJECT:([high_performance_sql].[dbo].[Post].[IDX_Post_Title]),|
|     SEEK:([high_performance_sql].[dbo].[Post].[Title]=[@P0]) ORDERED FORWARD)|

Table 'Post'. Scan count 1, logical reads 2, physical reads 0

由于相关的PostId主键列值存储在IDX_Post_Title叶节点中,因此此查询不需要额外查找来定位聚集索引中的Post行。