数据库的索引不是越多越好,索引会占用很大的空间,更多的索引维护,可能更多的查询,这需要达到一个平台, 推荐每个表的索引列在5个以下, 而且在创建表的过程中创建索引,扩展表时扩展索引, 后期增加索引会有相应的时间成本, 修改表结构都会导致锁表,导致业务中断
INNODB 支持几种常见的索引:
~B+树索引
B+树索引是磁盘管理使用的最多的索引方式, 是平衡二叉树的扩展,可以根据健值很快的查询到数据。B+树索引不能直接定位到数据库的具体某一行,因为innoDB存储的最小单位是页,查询到数据所在页中, 然后将整个页加载到内存,在从内存中查出具体的数据
~全文索引
~哈希索引,哈希索引是自适应的,不能人为的干预
2. B+树索引
B+树索引分为聚集索引和辅助索引(非聚集索引)
2.1 聚集索引
mysql的innoDB存储是以索引组织表,表中的数据按主键的顺序存放,聚集索引按每张表的主键构造一棵b+树,叶子节点存放表的记录, 叶子节点是一个数据页, 每个页之间用双向链表连接, 每张表只能有一个 聚集索引,查询优化倾向于采用聚集索引, 这样可以直接找到叶子的记录。 非叶子节点存放的是索引,节点中存放的健值以及子节点的偏向指针。 数据逻辑上顺序存储, 那么根据主键查询单条数据与范围查找速度非常快。
2.2 辅助索引
叶子节点不包含全部数据,而是存放着索引健与一个书签, 书签中存放着在数据行在什么地方,InnoDb是由索引组织表, 所以书签中存放的是聚集索引响应的索引健, 也就是聚集索引的主键。 只需要记住, 非聚集索引存放叶子节点存放聚集索引的主键就足够了。效率上非聚集索引要比具体索引效率低。
2.3 索引的管理
这儿不讲怎么添加删除索引,只对索引的几个关键地方进行解释,
首先执行语句:
show index from test1; 复制代码
Table: 索引所在的表名
Non_unique: 非唯一索引,唯一为0, 非唯一为1
Key_name:索引的名称
Seq_in_index:索引的位置,单列索引都为1, 组合索引会根据列的顺序1,2..
Column_name:索引列名
Collation:列一什么方式索引,B+树都是A, 其他的都是空, 表示排序的;
cardinality:非常关键,表示索引唯一值得估计,如果数目远小于记录数,索引基本没有什么用处, 最好与记录数接近。这个值不是常更新的,是一个估计值;
sub_part:是否部分索引,如果为NULL, 表示全表索引。
Packed:是否被压缩 Null:列是否包含空值
Index_type:索引类型, INNODB都是b+树索引
comment:注释
2.4 索引更改注意的地方
通常建议在创建表的时候创建索引, 在5.5之前是首先创建一张临时表, 导入原来的数据, 删除原始表,临时表重命名为原来的表, 这这样代价非常大。对于大表的索引创建与删除要花很长的时间, 如果原始表存在大量的事务,基本意味 着数据库不可用。
select version();
查看数据库的版本号,在5.5之后的版本, 增加了一种快速索引, 对在创建索引的表上加一个S锁,创建索引完成后释放, 删除时只需要删除内部视图, 然后释放索引空间。5.6开始支持Online ddl 在创建索引的参数中:
alter table table_name add {index|key} index_name (index_column)ALGORITHM=[DEFAULT|INPLACE|COPY]LOCK={default|NONE|SHARE|EXCLUSIVE} 复制代码
算法中inplace不需要创建临时表, copy需要, lock中,none表示不加合适锁,share表示S锁, EXCLUSIVE表示X锁, default自动判断 在实现online-ddl中,innodb引擎将操作日志写入到一个缓存中, 索引创建完成之后重新刷新数据到表中, 从而达到数据的一致性。
2.5 cardinality
在哪些字段添加索引了,where条件的中字段并不是全部要添加索引,这儿有一个原则, 对于高识别度的字段添加索引,也就是说, 重复的数据越少越好。 在index中有一个值, cardinality,表示不重复数据 的预估值,越是接近实际的记录数越好。当然数据量过大, 即时是唯一索引, 这个值可能不接近记录数, 因为大数据量是采用采样的方式去统计的,采用的过程不复杂,
2.6 联合索引
联合索引是一个索引包含多个字段, 那么字段的索引是有顺序的,只要按照顺序访问才会命中索引。比如索引列(a,b,c), 那么where a= and b = and c = 这样会命中索引,如果条件是a = and c = 那么c 不会命中, b = and c = 那么b和c 都不会命中。 所以联合索引除了单个索引的策略以外, 在注意顺序就好;
2.7 索引覆盖
查询只包含联合索引的字段速度很快, 因为索引字段会存储与叶子节点中,可以直接命中,如果查询多余的字段, 还需要进行聚集索引查询, 如果数据分散, 那么查询的速度也比较慢
3. 几种索引失败的问题
1)字段存在空 2)重复值较多 3)模糊查询前导% 4)带有or 5) 联合索引不使用第一部分 6)字符串不使用引号