MySQL 索引的介绍与应用
Mysql索引
一、 mysql 索引
索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。
二:MySQL索引类型
按存储结构区分:聚集索引(又称聚类索引,簇集索引),分聚集索引(非聚类索引,非簇集索引)
从数据结构角度 R-Tree索引 hash索引:
按键列个数区分:单列索引,多列索引
1.索引又分为普通索引,唯一索引,主键索引,组合索引
(1)、普通索引
ALTER TABLE tablename ADD INDEX index_name('column')
(2)、唯一索引
索引列的值必须唯一,但允许有空值,如果是组合索引,则列值的组合必须唯一
ALTER TABLE table_name ADD UNIQUE('column')
(3)、复合索引
(4)、主键索引
一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引,一个表只能有一个主键。
ALTER TABLE table_name ADD PRIMARY KEY('column')
(5)、全文索引
仅能用于MyISAM表,目前只有 CHAR、VARCHAR ,TEXT 列上可以创建全文索引,对于大容量的数据表,生成全文索引非常耗时间、磁盘空间
ALTER TABLE table_name ADD FULLTEXT('column')
1.直接创建索引和间接创建索引
直接创建索引: CREATE INDEX mycolumn_index ON mytable (myclumn)
间接创建索引:定义主键约束或者唯一性键约束,可以间接创建索引
2.普通索引和唯一性索引
普通索引:CREATE INDEX mycolumn_index ON mytable (myclumn)
唯一性索引:保证在索引列中的全部数据是唯一的,对聚簇索引和非聚簇索引都可以使用
CREATE UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn)
3.单个索引和复合索引
单个索引:即非复合索引
复合索引:又叫组合索引,在索引建立语句中同时包含多个字段名,最多16个字段
CREATE INDEX name_index ON username(firstname,lastname)
4.聚簇索引和非聚簇索引(聚集索引,群集索引)
聚簇索引:物理索引,与基表的物理顺序相同,数据值的顺序总是按照顺序排列
CREATE CLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) WITH
ALLOW_DUP_ROW(允许有重复记录的聚簇索引)
非聚簇索引:CREATE UNCLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn)
三、查看表结构
desc 表名
查看索引
show index from table_name;
explain
simple 表示简单的select,没有union和子查询
type 表示MySQL在表中找到所需行的方式,又称“访问类型”
type的参数(ALL, index, range, ref, eq_ref, const, system, NULL
从左到右,性能从最差到最好)
possible_keys 提示使用哪个索引会在该表中找到行,不太重要
keys 使用的索引,简单且重要
key_len 使用的索引长度
ref 列显示使用哪个列或常数与key一起从表中选择行
rows 显示MYSQL执行查询的行数,简单且重要,数值越大越不好,说明没有用好索引
Extra 该列包含MySQL解决查询的详细信息。
四:索引存储结构
存储结构分为四分类:顺序存储,链接存储,索引存储 ,散列存储(hash)
顺序结构和链接结构适合在内存中
索引存储和散列存储适合用在外存和内存交互结构中
顺序存储:在计算机中用一组地址连续的存储单元依次存储线性表的各个数据元素,称作线性表的顺序存储结构。
链接存储:在计算机中用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。它不要求逻辑上相邻的元素在物理位置上也相邻.因此它没有顺序存储结构所具有的弱点,但也同时失去了顺序表可随机存取的优点。
索引存储:除建立存储结点信息外,还建立附加的索引表来标识结点的地址。索引表由若干索引项组成。
散列存储:散列存储,又称hash存储,是一种力图将数据元素的存储位置与关键码之间建立确定对应关系的查找技术。
散列法存储的基本思想是:由节点的关键码值决定节点的存储地址。散列技术除了可以用于查找外,还可以用于存储。
,因此时间复杂度可以认为为O(1),而数组遍历的时间复杂度为O(n)。
五、索引的存储方式:
MyIsam和innodb数据和索引存储结构方式是不一样的。
Innodb主键索引是主键和数据列放在一起,每个普通索引都带着主键列,并且索引顺序是按照普通索引列和主键列排序;MyIsam主键索引是和数据列放开存放的,普通索引和主键索引没有任何区别,普通索引也不会保存主键索引的信息
六、索引的优点
1.创建唯一性索引,保证数据库表中每一行数据的唯一性
2.大大加快数据的检索速度,这也是创建索引的最主要的原因
3.加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
4.在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
5.通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能。
6.数据量,字段,内容相同的情况下,myisam比INNODB速度快
七、索引的缺点
1.创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加
2.索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大
3.当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度
八、索引的存储原理
1.InnDB(B+Tree)类似于二叉树查找法则
2.Hash 可以多个键值(key)可以对应一个数据(val),但是不能多一个键值(key)对应多个值(val)可以一次定位,具有居高的效率能完成逻辑查询操作(= In < = >)但是不能执行范围查询,它不利于数据库进行排序的优化
3.(R+Tree)相对于BTree又是在于范围查找上的优化
九、索引的应用场景
1.快速查找符合where条件的记录
2.多表做join操作时应该使用索引
3.若某字段已建立索引,求该字段的min()或max()时,MySQL会使用索引
4.对建立了索引的字段做sort或group操作时,MySQL会使用索引·
5.以%开头的like查询不能利用Btree索引
6.数据类型转换的时候不适宜用索引
7.不满足最左原则不适合用索引
8.有or条件的话,如有一方condition没有索引则不会使用索引
十、不同存储引擎下创建索引有何差异(innodb myisam)
1、 存储结构
MyISAM:每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.MYD (MYData)。索引文件的扩展名
是.MYI (MYIndex)。
InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。
2、 存储空间
MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。
InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。
3、 可移植性、备份及恢复
MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。
InnoDB:免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump,在数据量达到几十G的时候就相对痛苦了。
4、 事务支持
MyISAM:强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。
InnoDB:提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID
compliant))型表。
5、 AUTO_INCREMENT
MyISAM:可以和其他字段一起建立联合索引。引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。
InnoDB:InnoDB中必须包含只有该字段的索引。引擎的自动增长列必须是索引,如果是组合索引也必须是组合索引的第一列。
6、 表锁差异
MyISAM:只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。
InnoDB:支持事务和行级锁,是innodb的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的。
7、 全文索引
MyISAM:支持 FULLTEXT类型的全文索引
InnoDB:不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。
8、 表主键
MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址。
InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值。
9、 表的具体行数
MyISAM:保存有表的总行数
InnoDB:没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样。
10、 CURD操作
MyISAM:如果执行大量的SELECT,MyISAM是更好的选择。
InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE 从性能上InnoDB更优,但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate table这个命令。
11、 外键
MyISAM:不支持
InnoDB:支持
InnoDB自身很多良好的特点,比如事务支持、存储 过程、视图、行级锁定等等,在并发很多的情况下,相信InnoDB的表现肯定要比MyISAM强很多。
十一、使用索引的注意事项
使用索引时,有以下一些技巧和注意事项:
1.索引不会包含有NULL值的列
只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。
2.使用短索引
短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。
3.索引列排序
4.like语句操作(最左前缀)
一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。
5.不要在列上进行运算
例如:select * from users where YEAR(adddate)<2007;
6.不使用NOT IN和<>操作