1. 索引的种类
- B-Tree索引 //key(xx,xx,…)
- 哈希索引,将所有哈希码储存在索引当中,同时哈希表中保存指向数据的指针(只有Memory引擎支持哈希索引)//key using hash(xx,xx,…) Engine=Memory
特点:无法排序,只支持等值比较,不只是任何范围的查询;不储存字段;会有哈希冲突,冲突越多代价越大;不支持部分索引匹配查找
InnoDB有“自适应哈希索引”:当使用B-Tree时发现某索引值被使用的很频繁时会在内存中基于B-Tree之上再创建一个哈希索引
//set New.url_crc=crc32(New.url) - 空间数据索引(R-Tree) MyISAM引擎支持:无需前缀查询,会从所有的维度查询数据。
- 全文索引:查找的是文中的关键字,适用于MATCH AGAINST操作。
- 分形树索引:较新开发的数据结构
2. 索引的优点
- 快速找到表的指定位置
- 帮助服务器避免排序呵临时表
- 将随机I/O变为顺序I/O
TB级数据可用为块级别元数据技术储存
2.1 三星系统:
- 索引将相关的记录放在一起则获得一星;
- 索引中的数据顺序呵查找中的排序顺序一致则获得二星;
- 索引中二点列巴汗了查询中需要的全部列则获得三星;
3. 高性能索引策略
3.1 独立的列
(养成简化WHERE条件的习惯)
3.2 前缀索引呵索引选择性
前缀的基数应接近于完整类的基数
3.3 多列索引
在多个列上简历独立的单列索引并不能提高Mysql的查询性能。Mysql5.0和更新版本中引入了一种叫做”索引合并“的策略,一定程度上可以使用表上的多个单列索引来定位指定行。
如果在explain中看到索引合并,应该好好检查查询和表的结构,看是不是已经是最优的了。也可以i通过参数optimizer_switch来关闭索引合并功能。也可以使用ignore index提示让优化器忽略掉某些索引。
3.4 选择合适的索引列顺序
在”三星索引“系统中,列顺序也决定了一个索引是否能成为一个真正的三星索引。
经验法则:将选择性最高的列放在前面通常是最好的。这时候索引的作用只是用于优化where条件的查找。经验法则不总是使用,特殊情况下要特殊处理。比如某个特殊值特别行数异常多时,就要改变程序代码,区分这类特殊值。
3.5 聚簇索引
它并不是单独的索引类型,而是一种数据储存方式。InnoDB的聚簇索引实际傻瓜在同一个结构中保存了B-Tree索引和数据行。缺点,二级索引访问需要两次索引查找。对于InnoDB,自适应哈希索引能减少这样的重复操作。
3.5.1 InnoDB和MyISAM的数据分布对比
3.5.2 在InnoDB表中按主键顺序插入行
如果正在使用InnoDB表但是没有什么数据需要聚集,那么可以定义一个代理键(surrogate key)作为主键。最简单的办法是使用auto_increment自增列,保证数据行是按顺序写入,对于根据主键做关联操作的性能也会更好。
3.6 覆盖索引
如果一个索引包含所有需要查询的字段的值,就称之为”覆盖索引”。它是非常有用的工具,能够极大地提高性能。
如果查询只需要扫描索引而无需回表
好处:
- 索引条目远小于数据行大小,所以如果只需要读取索引,那么MySQL就会极大地减少数据访问量。
- 因为索引是按照列值顺序存储地,所以对于IO密集型地范围查询会比随即从磁盘上读取每一行数据的io要少得多。对于MyISAM和Percona XtraDB,甚至可以通过OPTIMIZE命令使得索引完全顺序排列。
- MyISAM在内存中只缓存索引,数据则依赖于操作系统来缓存,一次要访问数据需要一次系统级调用。这可能会导致严重的性能问题。
- 而InnoDB使用聚簇索引,所以覆盖索引对于InnoDB表特别有用。可以避免对主键索引的二次查询。