在MySQL中,索引(index)也叫作“键(key)”,它是存储引擎用于快速找到记录的一种数据结构。
单列索引mysql
ALTER TABLE `testDB`.`user` ADD INDEX `idx_name`(`name`) USING BTREE
组合索引redis
ADD INDEX `idx_mult`(`name`, `address`) USING BTREE
组合索引最左前缀原则
例如上面咱们建立了一个name, address的组合索引
select * from user where name = ‘xxx’ 此时,会走索引
select * from user where address = ‘xxx’ 则不会走索引算法
全文索引
首先,全文索引主要针对文本文件,好比文章,标题,全文索引只有MyISAM有效(mysql5.6以后InnoDB也支持了全文索引)sql
create table c( id int primary key auto_increment , title varchar(20), content text, fulltext(title,content) )engine=myisam charset utf8; insert into c(title,content) values ('MySQL Tutorial','DBMS stands for DataBase ...'), ('How To Use MySQL Well','After you went through a ...'), ('Optimizing MySQL','In this tutorial we will show ...'), ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), ('MySQL vs. YourSQL','In the following database comparison ...'), ('MySQL Security','When configured properly, MySQL ...');
惟一索引数据库
ADD UNIQUE INDEX `idx_unique`(`en_name`);
主键是一种约束,惟一索引是一种索引,二者在本质上是不一样的。
主键建立后必定包含一个惟一性索引,惟一性索引并不必定就是主键。
惟一性索引列容许空值,而主键列不容许为空值。
主键列在建立时,已经默认为空值 + 惟一索引了。
主键能够被其余表引用为外键,而惟一索引不能。
一个表最多只能建立一个主键,但能够建立多个惟一索引。
主键更适合那些不容易更改的惟一标识,如自动递增列、身份证号等。缓存
通常有四种索引方式(BTREE,RTREE, HASH ,FULLTEXT)
B+Tree相对于B-Tree有几点不一样:
非叶子节点只存储键值信息。
全部叶子节点之间都有一个链指针。
数据记录都存放在叶子节点中。数据结构
HASH索引工具
R-Tree索引
R-Tree在MySQL不多使用,仅支持geometry数据类型,支持该类型的存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种。性能
FULLTEXT索引
即为全文索引,目前只有MyISAM引擎支持。其能够在CREATE TABLE ,ALTER TABLE ,CREATE INDEX 使用,不过目前只有 CHAR、VARCHAR ,TEXT 列上能够建立全文索引。
值得一提的是,在数据量较大时候,现将数据放入一个没有全局索引的表中,而后再用CREATE INDEX建立FULLTEXT索引,要比先为一张表创建FULLTEXT而后再将数据写入的速度快不少。
它的出现是为了解决WHERE name LIKE “%word%"这类针对文本的模糊查询效率较低的问题。mysql索引
(1)对于BTREE这种Mysql默认的索引方式,具备广泛的适用性 (2)因为FULLTEXT对中文支持不是很好,在没有插件的状况下,最好不要使用。其实,一些小的博客应用,只须要在数据采集时,为其创建关键字列表,经过关键字索引,也是一个不错的方法,至少我是常常这么作的。 (3)对于一些搜索引擎级别的应用来讲,FULLTEXT一样不是一个好的处理方法,Mysql的全文索引创建的文件仍是比较大的,并且效率不是很高,即使是使用了中文分词插件,对中文分词支持也只是通常。 真要碰到这种问题,Apache的Lucene或许是你的选择。 (4)正是由于hash表在处理较小数据量时具备无可比拟的素的优点,因此hash索引很适合作缓存(内存数据库)。如mysql数据库的内存版本Memsql,使用量很普遍的缓存工具Mencached,NoSql数据库redis等,都使用了hash索引这种形式。 固然,不想学习这些东西的话Mysql的MEMORY引擎也是能够知足这种需求的。
扩展:
1.索引没法存储null值
a.单列索引没法储null值,复合索引没法储全为null的值。为何索引列没法存储Null值?
a.索引是有序的。NULL值进入索引时,没法肯定其应该放在哪里。(将索引列值进行建树,其中必然涉及到诸多的比较操做,null 值是不肯定值没法比较,没法肯定null出如今索引树的叶子节点位置。)
b.若是须要把空值存入索引,方法有二:其一,把NULL值转为一个特定的值,在WHERE中检索时,用该特定值查找。其二,创建一个复合索引。例如 create index ind_a on table(col1,1);
经过在复合索引中指定一个非空常量值,而使构成索引的列的组合中,不可能出现全空值。
不适合键值较少的列(重复数据较多的列)
假如索引列TYPE有5个键值,若是有1万条数据,那么 WHERE TYPE = 1将访问表中的2000个数据块。
再加上访问索引块,一共要访问大于200个的数据块。
若是全表扫描,假设10条数据一个数据块,那么只需访问1000个数据块,既然全表扫描访问的数据块少一些,确定就不会利用索引了。
索引失效的几种状况
1.若是条件中有or,即便其中有条件带索引也不会使用(这也是为何尽可能少用or的缘由),要想使用or,又想让索引生效,只能将or条件中的每一个列都加上索引 2.对于多列索引,不是使用的第一部分,则不会使用索引 3.like查询以%开头(例如where code like '%AB'条件是不会走索引的,而where code like 'AB%'条件是会走索引的) 4.若是列类型是字符串,那必定要在条件中将数据使用引号引用起来,不然不使用索引 5.若是mysql估计使用全表扫描要比使用索引快,则不使用索引