码迷,mamicode.com
首页 > 数据库 > 详细

mysql索引介绍

时间:2017-11-28 15:43:49      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:dex   就会   sam   ase   例子   如何使用   article   plain   查询   

0.索引的概念
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。好比是一本书前面的目录,能加快数据库的查询速度。
无论是Myisam和Innodb引擎,如果在建表的时候没有显示的定义一行主键列的话,他内部都会自动创建一个隐藏的主键索引;
 
1.索引的优点:
a.大大减少服务器需要扫描的数据量
b.帮助服务器避免排序和临时表
c.将随机IO变为顺序IO
 
2.“三星 ”系统:
索引将相关的记录放在一起,获得一星
索引中的数据顺序和查找中的排列顺序一直,再获得一星
索引中的列涵盖了查询中需要的全部列,再获得一星
 
3.按照实现方式来划分的索引类型
哈希索引:基于哈希表实现,只有精确匹配索引所有列的查询才有效,只有Memory引擎实现
空间数据索引(R-Tree ),只有MyISAM引擎实现
全文索引:分词后查找关键词,适用于match against操作
BTree索引:B-Tree索引的限制:如果不是按照索引的出现顺序查找,则无法使用索引;不能跳过索引中的列,否则后面的索引无效;如果查询中有某个列的范围查询,则其右边所有列都无法使用索引优化查找;
B+Tree索引:适用于全键匹配、第一列匹配(组合索引)、列前缀匹配,范围值匹配、精确匹配第一列并范围匹配第二列、只访问索引(也称索引覆盖)匹配;
 技术分享图片

 

 MyISAM和InnoDB上都是采用B+Tree索引,但是实现方式完全不同。具体可参考 

MySQL的MyISAM与InnoDB的索引方式

https://www.cnblogs.com/zlcxbb/p/5757245.html
4.索引分为聚簇索引和非聚簇索引两种
innodb采用聚簇索引:主键索引的叶子节点下面直接存放数据,其他次索引的叶子节点指向主键id;聚簇索引能提高多行检索的速度。
myisam采用非聚簇索引 :主键索引的叶子节点只存放数据在物理磁盘上的指针,其他次索引也是一样的;非聚簇索引对于单行的检索很快
 
 
5.按照使用方式来划分索引类型

a.普通索引INDEX  :这是最基本的索引,它没有任何限制。

b.唯一索引UNIQUE:与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一

c.主键索引PRIMARY KEY:它 是一种特殊的唯一索引,不允许有空值。 

d.全文索引FULLTEXT :仅可用于 MyISAM 表,针对较大的数据,生成全文索引很耗时耗空间。

e. 单列索引、多列索引:多个单列索引与单个多列索引的查询效果不同,因为执行查询时,MySQL只能使用一个索引,会从多个索引中选择一个限制最为严格的索引。

f.组合索引:为了榨取MySQL的效率,就要考虑建立组合索引。例如表中针对title和time建立一个组合索引:ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))。建立这样的组合索引,其实是相当于分别建立了下面两组组合索引,为什么没有time这样的组合索引呢?这是因为MySQL组合索引“最左前缀”的结果。简单的理解就是只从最左面的开始组合。并不是只要包含这两列的查询都会用到该组合索引

–title,time
–title
 
6.索引覆盖:如果要查找的数据恰好是索引列,那么就不用在去物理磁盘上去找数据了,就是不用回行,称为索引覆盖;
 
7.索引优化:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。
a. 何时使用聚集索引或非聚集索引?
动作描述 使用聚集索引 使用非聚集索引
列经常被分组排序 使用 使用
返回某范围内的数据 使用 不使用
一个或极少不同值 不使用 不使用
小数目的不同值 使用 不使用
大数目的不同值 不使用 使用
频繁更新的列 不使用 使用
外键列 使用 使用
主键列 使用 使用
频繁修改索引列 不使用 使用
事实上,我们可以通过前面聚集索引和非聚集索引的定义的例子来理解上表。如:返回某范围内的数据一项。比如您的某个表有一个时间列,恰好您把聚合索引建立在了该列,这时您查询2004年1月1日至2004年10月1日之间的全部数据时,这个速度就将是很快的,因为您的这本字典正文是按日期进行排序的,聚类索引只需要找到要检索的所有数据中的开头和结尾数据即可;而不像非聚集索引,必须先查到目录中查到每一项数据对应的页码,然后再根据页码查到具体内容。
b. 索引不会包含有NULL值的列
只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。
c. 使用短索引
对字符串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。mysql不允许索引这些列(BLOB、TEXT、很长的VARCHAR)的完整长度
d. 索引列排序
MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
只有当索引的列顺序和order by子句的顺序完全一致,并且所有列的排序方向一致时,mysql才能用索引来对结果做排序
e. like语句操作:一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引。而like “aaa%”可以使用索引。
f. 不要在列上进行运算:
例如:select * from users where YEAR(adddate)<2007,将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成:select * from users where adddate<’2007-01-01′
 g.多列索引:
如果对多个单独索引做AND条件查询时,应该将多个单独索引合并为一个多列索引。
如果对多个单独索引做OR条件查询,会消耗大量CPU、内存在算法的缓存、排序和合并上。应该将多个单独索引合并为一个多列索引。
使用explain检查sql 语句,如果发现了索引合并问题,应该修改sql语句
选择合适的索引列顺序,选择性高的列往前放
h.覆盖索引:如果一个索引包含所有要查询的字段值(三星系统中第三星),较少了磁盘IO操作,提高查询性能
i.索引不能太多:索引越多会导致更新表的速度减慢,因为除了更新数据外,还要更新索引
j:MySQL只对以下操作符才使用索引 <,<=,=,>,>=,between,in,以及某些时候的like(不以通配符%或_开头的情形)。而理论上每张表里面最多可创建16个索引,不过除非是数据量真的很多,否则过多的使用索引也不是那么好玩的
 
 
 
 
8.非聚簇索引和.聚簇索引
非聚集索引,类似于图书的附录,那个专业术语出现在哪个章节,这些专业术语是有顺序的,但是出现的位置是没有顺序的。每个表只能有一个聚簇索引,因为一个表中的记录只能以一种物理顺序存放。但是,一个表可以有不止一个非聚簇索引。
MyISAM是非聚簇索引,B+Tree的叶子节点上的data,并不是数据本身,而是数据存放的地址。主索引和辅助索引没啥区别,只是主索引中的key一定得是唯一的。这里的索引都是非聚簇索引。非聚簇索引的两棵B+树看上去没什么不同,节点的结构完全一致只是存储的内容不同而已,主键索引B+树的节点存储了主键,辅助键索引B+树存储了辅助键。表数据存储在独立的地方,
这两颗B+树的叶子节点都使用一个地址指向真正的表数据,对于表数据来说,这两个键没有任何差别。由于索引树是独立的,通过辅助键检索无需访问主键的索引树。InnoDB的数据文件本身就是索引文件,B+Tree的叶子节点上的data就是数据本身,key为主键,这是聚簇索引。聚簇索引,叶子节点上的data是主键(所以聚簇索引的key,不能过长)。
 
聚簇索引的数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的。聚簇索引要比非聚簇索引查询效率高很多。
聚集索引这种主+辅索引的好处是,当发生数据行移动或者页分裂时,辅助索引树不需要更新,因为辅助索引树存储的是主索引的主键关键字,而不是数据具体的物理地址。

 InnoDB是聚簇索引,将主键组织到一棵B+树中,而行数据就储存在叶子节点上,若使用"where id = 14"这样的条件查找主键,则按照B+树的检索算法即可查找到对应的叶节点,之后获得行数据。若对Name列进行条件搜索,则需要两个步骤:第一步在辅助索引B+树中检索Name,到达其叶子节点获取对应的主键。第二步使用主键在主索引B+树种再执行一次B+树检索操作,最终到达叶子节点即可获取整行数据。

 
技术分享图片

 9.mysql索引和页的关系

索引往往以索引文件的形式存储的磁盘上,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。为了达到这个目的,磁盘按需读取,要求每次都会预读的长度一般为页的整数倍。而且数据库系统将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。并把B-tree中的m值设的非常大,就会让树的高度降低,有利于一次完全载入。 内存管理内容可参考操作系统内存管理
 

mysql索引介绍

标签:dex   就会   sam   ase   例子   如何使用   article   plain   查询   

原文地址:http://www.cnblogs.com/wzj4858/p/7909666.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!