索引:可以包含一个或者多个列的值。如果索引包含多个列,那么列的顺序非常重要,因为mysql只能高效地使用索引的最左前缀列。
索引类型
B-Tree索引:大多数Mysql引擎都支持这种索引。
树结构:http://blog.csdn.net/qq_23211905/article/details/72781842
B-tree能加快访问数据的速度,因为存储引擎不在需要进行全表扫描来获取需要的数据,取而代之的是重索引的根节点开始进行搜索。根节点的槽中 存放了指向子节点的指针,存储引擎根据这些指针往下层查找。通过比较节点页的值和要查找的值可以找到合适的指针进入下层节点。
叶子节点比较特别:他们的指针指向的是被索引的数据,而不是其他的节点页。索引列是顺序存储的,适合查找范围数据。
B-Tree索引适用于全键值、键值范围或者键前缀查找。
全值匹配:和索引中的索引列进行匹配。
匹配最左前缀:索引的第一列
匹配列前缀:匹配某一列的值的开头部分。
匹配范围值:使用索引的第一列
只访问索引的查询:查询只需要访问索引,无须访问数据行。
精确匹配某一列并范围匹配另外一列:第一列全匹配,第二列部分匹配。
索引的限制
1. 如果亅按照索引的最左列开始查找,则无法使用索引。
2. 不能跳过索引中的列。
3. 如果查询中有某个列的范围查询,则其邮编索引列都无法索引索引优化查找。即先匹配前面的索引,后面的索引失效。
哈希索引
哈希索引:基于哈希表实现,只有精确匹配索引所有列的查询才有效。对于某一行数据,存储引擎都会对多余的索引列计算一个哈希吗,哈希吗是一个较小的值,并且不同键值的行计算出的哈希吗也不一样。哈希索引将所有的哈希码存储咋索引中,同时哈希表八成指向每个数据行的指针。
MYSQL 引擎中 只有memory支持哈希索引。
哈希索引限制
1. 哈希索引只包含哈希值和行指针,不存储字段值,所以不能使用索引中的值来避免读取行。
2. 哈希索引数据并不是安装索引值顺序存储的,索引无法用于排序。
3. 哈希索引外部支持部分索引匹配查找,因为哈希索引始终是使用索引列的全部内容计算哈希值。
4. 哈希索引只支持等值比较查询
5. 访问哈希索引的数据非常快,除非有很多哈希冲突。
空间数据索引
MYISAM 表支持空间索引,可以用作地理数据存储。
全文索引
全文索引适一直特殊的索引,它查找额是文本中的关键词,我如实直接比较索引中的值。
索引的优点
1. 索引大大减少服务器需要扫描的数据量
2. 索引可以帮忙服务器避免排序和临时表
3. 索引可以将随机I/O 变为顺序I/O
索引适合中到大型的表,特大型表需要另外考虑。如果表数据量特别多,可以建立元数据信息表,用来查询需要用到的某些特征。
高性能索引的策略
1. 独立的列:指的是所有不能是表达式的一部分,也不能是函数的参数,即索引的不能不能是函数。
2. 前缀索引和索引的选择性:索引的字符串很长,会影响索引的性能。索引的选择性是指,不重复的索引值和数据表的记录总值的比例,范围是是1/count到1之间。索引的选择性越高查询效率越高。唯一索引的选择性是1,性能是最好的。
如何选择合适长度的前缀以保证较高的选择性,同时不能太长(节约空间)。
* 多列索引*
mysql 5.0引入了“索引合并”的策略。单独的索引并不是最好的选择结构,最好通过组合索引。
选择合适的索引顺序,最好的索引首先按照最左边列进行排序,其次是第二列。所以索引可以按照升序或者降序进行扫描,以满足符合列顺序的条件。
将选择性最高的列放在索引的最前列或许是个好的选择。但是不如避免随机io和排序那么重要。
聚簇索引
聚簇索引并不是单独的索引类型,而是一直数据存储的方式。实际上是在同一结构中保存B-tree和数据行。叶子页包含行的全部数据,节点页只包含索引列。
当表有聚簇索引时,它的数据实际上存放在叶子页。即数据行和相邻的键值紧凑的存储在一起。
存储因此负责实现索引,因此不是所有的存储引擎都支持聚簇索引。
聚集的数据有一些优点:
1. 可以把相关数据保存在一起。
2. 数据访问更快。
3. 使用覆盖索引扫描的查询可以直接使用页节点中的主键值。
缺点:
1. 聚簇索引最大限度地提高了I/O密集型应用的性能,但如果数据都防止内存中,访问的顺序就没有那么重要了。
2. 插入速度严重依赖插入顺序。
3. 更新代价很高
4. 基于聚簇索引的表在插入新行,或者主键被更新操作导致要移动行的时候,可能面临页分裂的问题。
5. 聚簇索引可能导致全部扫描变慢,尤其是行比较稀疏。
6. 二级索引可能比想象的要更大。
使用UUID
覆盖索引
mysql可以直接使用索引来直接获取列的数据,这样就不需要读取数据行。如果索引包含(或者说覆盖)所有需要查询的字段值,我们称为”覆盖索引”。
扫描索引无须回表带来的好处:
1. 索引条目通常小于数据行,如果只需要读取索引,那么mysql就会极大地减少数据访问量。
2. 索引是按照列值顺序存储,所以对于I/O密集的范围查询会比随机从磁盘读取每一行数据的I/O少的多。
3. 一些存储引擎如MyISAM 在内存中只缓存索引,数据则依赖操作系统来缓存,因此要访问数据需要一次系统调用。会导致性能问题
4. 由于InnoDB的聚簇索引,覆盖索引对InnoDB表特别有用。