前言1:我会结合mysql和mssql来写。虽然是不一样的数据库,可是两者索引的本质是同样的。mysql
前言2:业务系统大多数时间无非动态条件+排序+查找,如何提高排序查找效率乃重中之重算法
前言3:程序猿的救命稻草——建立索引sql
若是你对前言的内容感兴趣(怎么会有兴趣呢,很痛苦好吧。。。)不过为了未来数据库
请继续往下看吧bash
1 索引的定义数据结构
不须要太多术语,就一句话:快速查找&有序 的数据结构工具
堆表不保证有序性能
汇集索引Clustered Index
1 列能够有重复值。
2若是主键默认作汇集索引,则符合惟一约束.
3索引组织表是有序的,堆表是无序的。
4只能有一个
5mysql的表就是一张索引组织表,若无主键,InnoDB engine会自动建立一个6字节(48bit)列做为主键。mssql则不会
6当select * 的时候,检索最快,由于叶子节点有所有的数据
非汇集索引NonClustered Index
1叶子节点上保存二个信息:索引字段值,对应汇集索引键值(无汇集索引,则是数据位置的指针)
2select * 浪费性能,须要标签查找。select 非汇集列 则最快复制代码
快问快答——ui
主键和汇集索引有什么区别?miemiemie~~spa
3 索引在执行计划中的术语
结构
|
SCAN
|
SEEK
|
堆(没有汇集索引的表格数据页)
|
Table Scan
没有汇集索引
|
无
|
汇集索引
|
Clustered Index Scan
有汇集索引,但也是全表扫描
|
Clustered index seek
用索引结果检索Data
|
非汇集索引
|
Index Scan
有非汇集索引,只是小部分Data扫描,比整表扫描代价小得多
|
index seek
用索引结果检索Data
|
1 索引是一个B+树
B+树的概念,网上一大堆,这里不赘述。我用一个图来展现B+树是如何插入元素的。
2 索引插入算法—— 灵魂画手
3 索引分页三个基本类型
汇集索引结点级(非leaf),汇集索引叶级别(就是数据行),非汇集索引结点级,非汇集索引的叶级别。
下一个章节会对索引分页详细说明,其中汇集索引叶级别,非汇集索引结点级不作细节介绍。
1 Sqlserver 一个分页是8k,mysql一个分页则是16k。存储理论是一致的。
2
PageType(分页类型)
|
1:数据页面;2:索引页面;3:Lob_mixed_page;4:Lob_tree_page;10:IAM页面
|
IndexID (索引ID)
|
0 表明堆, 1 表明汇集索引, 2-250 表明非汇集索引 ,大于250就是text或image字段
|
sysindexes keycnt
|
0堆;1惟一汇集索引;2不带惟一汇集索引、惟一非汇集索引
|
A汇集索引的节点行(非leaf)
组成:索引键值+下级指针
dbcc page(test,1,162,1) --索引leafdbcc page(test,1,178,1) -- 索引节点dbcc page(test,1,898,1) --根索引复制代码
B非汇集索引的叶级行
1 非汇集索引+堆表
组成:非汇集键+ RID
组成:非汇集键值+汇集键值
组成:非汇集键值+向下指针
1 在项目中,我见过索引列数据类型是 varchar(500)的
做为索引键值的列,数据类型太大
从上面能够得知,数据页大小是固定的.
一个索引行越长,那么一个数据页所能容纳的索引就越少,这样索引树就会复杂。
查询的时候产生的io就越多。
而数据库的查询处理器在选择执行计划的时候,若是使用索引的成本过高,那么数据库就会选择全表扫描,那么添加索引的意义在哪儿呢?复制代码
2物理表随意加索引
从问题1过渡过来,若是索引过多了,会怎样呢?
有的攻城狮真的不要太大方,索引嗷嗷的加。最后索引比真正数据文件还要大。。。
索引是落磁盘的,是增长存储压力的。索引越多统计信息就越多,写入会变慢。
那么,应该怎么加呢?
应该参考业务需求,热点表热点查询加索引,争取一个索引能够覆盖多个查询。复制代码
/*
* 索引实际大小
* 获得索引名字
* Jaki Wang
*/
create function fn_Index_name(@object_id int,@index_id int)
returns sysname
as
begin
declare @index_name sysname
select @index_name = name
from sys.indexes
where object_id=@object_id and index_id=@index_id
return @index_name
end复制代码