认识窄索引
很多书籍和文章都写过索引要使用窄索引,窄索引是个什么东东呢,大白话就是把索引建在字节长度比较小的列上,比如int占用4个字节,bigint占用8个字节,char(20)占用20个字节nchar(20)最占用40个字节,那么int 相对于bigint来说就是窄了(占用字节数更少),bigint比char(20)也要窄,char(20)和nchar(20)相比要窄(nchar(20)每个字符占用2个字节)。
明白了啥是窄索引我们来说下为什么要使用窄索引,我们知道数据存储和读取的最小单位是页,一个页8K大小,当使用比较窄的列做索引列时,每个页能存储的数据就更多,以int和bigint为例,一个8K的页大约能存储81024/4(int 4个字节)=2048(实际值要比这个数字小)条数据,使用bigint大约能存储81024/8(bigint为8个字节)=1024(实际值要比这个数字小)条数据,也就是说索引列的长度也小,每个页能存储的数据也就越多,反过来说就是存储索引所需要的页数也就越少,页数少了进行索引查找时需要检索的页自然也就少了,检索页数少了IO开销也就随之减少,查询效率自然也就高了
CREATE TABLE [dbo].[t1](
t1_id int NOT NULL
)
字段类型为int,添加值
查询表所占页数
—通过 sys.dm_db_partition_stats系统表获取用户数据表的占用情况
SELECT o.name ,
分配页数 = SUM (reserved_page_count),
[数据占用页数]= SUM (CASE WHEN (index_id < 2) THEN (in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count) ELSE 0 END),
[索引占用页数]=case when sum(used_page_count)>SUM (CASE WHEN (index_id < 2) THEN
(in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count) ELSE 0 END) then
sum(used_page_count)-SUM (CASE WHEN (index_id < 2) THEN (in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count) ELSE 0 END)
else 0 end ,
[表行数] = SUM (CASE WHEN (index_id < 2) THEN row_count ELSE 0 END),
[未使用页数]=case when SUM (reserved_page_count)>SUM (used_page_count) then SUM (reserved_page_count)-SUM (used_page_count) else 0 end
FROM sys.dm_db_partition_stats p join sys.sysobjects o on p.object_id=o.id and o.xtype=‘U’
where object_id= object_id(‘t1’)
group by o.name
order by SUM (CASE WHEN (index_id < 2) THEN row_count ELSE 0 END) desc
创建索引
create index idx_t1 on [dbo].[t1] (t1_id);
查询表所占页数
删除索引
drop index idx_t1 on [dbo].[t1]
修改字段类型为varchar(10),数据不变
查询表所占页数
添加索引
create index idx_t1 on [dbo].[t1] (t1_id);
查询表所占页数
假如字段类型修改为varchar(20),数据不变,所占页数和varchar(10)的结果也是一样的。
如果字段类型改为nvarchar(10)。所占页数又会变大。
字段类型所占字节数请参考:https://www.cnblogs.com/mslong/p/13787026.html
参考文章:
https://www.cnblogs.com/lzrabbit/archive/2012/06/11/2517963.html