索引,索,检索之意,引,引用之意。
百度百科的解释如下:
索引,指将文献中具有检索意义的事项(可以是人名、地名、词语、概念、或其他事项)按照一定方式有序编排起来,以供检索的工具书。
从上面的文字解释中,我们知道索引是为了查询,检索方便,快速而生的。
实现索引的技术很多,但是这些实现索引的初中都是一样的,就是为了查询方面,效率高,特别在数据量非常大情况下。
在mysql中,常见的索引,是b-tree。
索引的演进过程如下:
1. 将指定的列内容进行按照一定的数据结构(b-tree结构),进行索引,并 且放到一个磁盘的block(块)。
2.当使用该列进行检索时,mysql服务器会到索引数据块(block),进行检索数据,定位到要查询的数据后,然后根据该索引的指针,去到表所在的块(block)直接定位到数据行(row)。
在这个过程中,索引的数据量和整个表的数据量比较,是非常少的,查询效率自然比全表扫描快。
3.使用索引扫描来做排序
mysql有两种方式生产有序的结果,一个是通过排序操作,一个是按照索引顺序扫描;扫描索引是很快的,只需要从一条索引记录移动到紧接着的下一条。但是如果索引不能覆盖查询的全部列,那就不得不每扫描一条索引记录就都回表查询一次对应的行。这基本都是随机I/O,因此通过索引顺序读取数据的速度通常要比顺序地全表扫描慢,尤其在I/O密集型的工作负载时。
那么,怎么判断一个sql是否使用了索引顺序扫描呢,在explain中,如果type的值是index,那么就说明使用了索引顺序扫描。另外,在explain中,extra列的值为Using index则表示使用了索引覆盖查询。这点要区分开,不要混淆。
4.当数据量又变得很大的情况下,简单的索引(稠密索引)效率就需要再次进一步设计,这个时候,稀疏索引就出现了。稀疏索引就是把索引进行再次索引,是按照分组的形式对索引进行索引,那么当通过该索引列进行范围查找的时候,就可以先通过索引的索引进行查询,定位个大致范围,然后再去索引中去找,最后再通过索引的指针去定位数据,这样分组后的索引的索引就比索引小很多,效率自然会好。
索引的索引,即把索引分组,那么前提是索引必须是有序的,分组中就包含了排序。这里就是分层的体现,如此进行向上层递推,那么最上层的索引组不能再分组为止。(多层稀疏)
总结,虽然对列数据进行索引,也占用额外的空间,如果一个表是10个字段,那么每列都占一行的十分之一,假设一个表共有一行,一行的大小是10kb,假设第一列是主键列,那么对第一列的数据建立一个索引,额外需要1kb的空间,对第二列建立索引,额外需要1kb或者稍大点的空间,那么当你使用第一列或者第二列查询时,那么只需要扫描1kb的磁盘大小而不是扫描10kb的大小,这就是空间换时间。
索引可以提升查询效率,那么维护索引自然也是耗费资源的,所以insert ,update的效率就相对下降了,但是现实是,一般系统的查询总是远远大于修改,所以还是值得的。
主键列索引,如果是b-tree索引,那么该索引存储了列的数据值,而哈希索引、空间索引、全文索引等都不存储索引列的值。因此,mysql只能使用b-tree索引做覆盖索引。另外,一些存储引擎,比如myIsAm可以对索引做压缩,让索引的占用的磁盘空间更小。在InnoDB引擎中的二级索引不但要对索引的列建立索引,还要存储主键列数据,因此,二级索引的占用空间稍大点,不过,这点经常被用来延迟关联查询(通过使用覆盖索引查询需要的主键,再根据这些主键关联原表获取需要的行,二级索引中有主键,因此不需要回表,如果在需要排序并且数据量特别大的情况下,这种延迟关联查询很有效)。
索引的维护:
连接数据库后,可以通过命令,
show index from tablename \G;
查询某个表的索引的统计信息。
其中的索引列的技术(Cardinality),其显示了存储引擎估算索引列有多少不同的取值,这可以表明索引的选择性高低。
注意,这个命令会触发索引统计信息的更新,还有show table status、或者InnoDB在打开某些information_schema表,或者mysql客户端开启自动补全功能的时候,都会触发,这样的话,如果服务器上又大量的数据,这可能造成很严重的问题,尤其是I/O比较慢的时候,所以,可以关闭innodb_status_on_metadata来避免上面的问题,具体设置参考
http://dev.mysql.com/doc/refman/5.0/en/using-system-variables.html