Cra*_*ein 4 index sql-server storage-engine
我有一个表 people 有两个非聚集索引。
create table people(
id_person int,
first_name varchar(50),
last_name varchar(50),
city varchar(100),
state char(2),
zip_code int
)
CREATE INDEX id_first_name_last_name ON people(first_name, last_name, id_person)
CREATE INDEX id_last_name_first_name ON people(id_person, last_name, first_name)
Run Code Online (Sandbox Code Playgroud)
每个索引引用相同的列,但顺序不同。
-- 插入一些行
insert into people values(1,'joe','smith','new york', 'NY', 10701)
insert into people values(2,'john','smith','new york', 'NY', 10701)
insert into people values(3,'joyce','smith','new york', 'NY', 10701)
insert into people values(4,'jocelyn','smith','new york', 'NY', 10701)
Run Code Online (Sandbox Code Playgroud)
每个索引的大小如下
TableName IndexName IndexID Indexsize(KB)
people NULL 0 16
people id_first_name_last_name 2 16
people id_last_name_first_name 3 16
Run Code Online (Sandbox Code Playgroud)
每个索引使用 16KB。
现在,如果我在 id_person 上添加聚集索引
create clustered index ix_id_people on people(id_person)
Run Code Online (Sandbox Code Playgroud)
我最终得到每个索引使用的空间量相同。
TableName IndexName IndexID Indexsize(KB)
people NULL 1 16
people id_first_name_last_name 2 16
people id_last_name_first_name 3 16
Run Code Online (Sandbox Code Playgroud)
唯一的区别是现在我有一个聚集索引而不是 HEAP。
我期望通过 id_person 上的聚集索引,存储引擎将不再需要在每个非聚集索引中包含 id_person。
问题:
非聚集索引引用的每个列的值是否仅存储为第一个非聚集索引,然后由所有其他非聚集索引引用?
如果非聚集索引引用了聚集索引列,那么该列中的值是物理复制到每个非聚集索引上还是只是简单地引用?
更新 14:55
这是用于计算索引大小的查询
SELECT
OBJECT_NAME(i.OBJECT_ID) AS TableName,
i.name AS IndexName,
i.index_id AS IndexID,
8 * SUM(a.used_pages) AS 'Indexsize(KB)'
FROM sys.indexes AS i
JOIN sys.partitions AS p ON p.OBJECT_ID = i.OBJECT_ID AND p.index_id = i.index_id
JOIN sys.allocation_units AS a ON a.container_id = p.partition_id
GROUP BY i.OBJECT_ID,i.index_id,i.name
ORDER BY OBJECT_NAME(i.OBJECT_ID),i.index_id
Run Code Online (Sandbox Code Playgroud)
非聚集索引总是包含一个行定位符。
对于堆,这将是一个 8 字节的 RID (File:Page:Slot)。在具有聚集索引的表上,它将是聚集索引键列。它始终是复制的值,而不是指向值的指针。将 CI 键值复制到所有非聚集索引中,这就是为什么经常建议将 CI 键缩小而不频繁更新的原因。
在问题中显示的表中,聚集索引键是一个 4 字节整数,并且可能还包括任何重复键值的 4 字节唯一标识符。
在您的情况下,由于 NCI 未声明为唯一,CI 密钥将附加到 NCI 密钥。
对于唯一的非聚集索引,除非明确地将 CI 键作为包含列添加到叶页中,否则该键将被添加为键的一部分。
请参阅Kalen Delaney: More About Nonclustered Index Keys以了解有关如何自己查看的更多信息。
对于这 4 行数据,所有三个索引仅消耗单个 8KB 数据页。
SELECT index_id,
index_level,
page_count,
record_count
FROM sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID('people'), NULL, NULL, 'DETAILED')
Run Code Online (Sandbox Code Playgroud)
退货
+----------+-------------+------------+--------------+
| index_id | index_level | page_count | record_count |
+----------+-------------+------------+--------------+
| 1 | 0 | 1 | 4 |
| 2 | 0 | 1 | 4 |
| 3 | 0 | 1 | 4 |
+----------+-------------+------------+--------------+
Run Code Online (Sandbox Code Playgroud)
使用中显示的附加页面sys.allocation_units.total_pages
是IAM 页面。这不用于存储数据,而仅用于跟踪构成索引的页面和范围。
归档时间: |
|
查看次数: |
2772 次 |
最近记录: |