索引的存储类型目前只有两种(btree和hash),具体和表的模式相关:
myisam btree
innodb btree
memory/heap hash,btree
mysql中索引分为:
目前只有MyISAM存储引擎支持全文索引(目前对中文不支持),InnoDB引擎还不支持全文索引
针对字段属性为char和varchar的如果该字段的值很大,建立索引最好是建立前缀索引,最下面将进行建立前缀索引和使用普通索引进行测试
普通索引:针对所有的列都可以建立 格式:index
唯一索引:选择建立索引的列值不能有相同 格式:unique index
全文索引:列值的属性必须是char(),varchar(),test() 格式:fulltext index
单列索引:
多列索引:create index index_name on table_name(colum_name1,colum_name2)
colum_name1这个是必须有的
在使用了索引后的效果查询速度提高了n多倍,缺点是建立索引会占用与表几乎接近相同大小的空间
友情提示:
对于myisam表,如果创建组合索引,所创建的索引长度和不能超过1000 bytes,否则会报错,创建失败;对于myisam的单列索引,最大长度也不能超过1000,否则会报警,但是创建成功,最终创建的是前缀索引(取前333个字节)。
对于创建innodb的组合索引,如果各个列中的长度不超过767,则不再计算所有列的总长度,如果有超过767的,则给出报警,索引最后创建成功,但是对于超过767字节的列取前缀索引;对于innodb的单列索引,超过767的,给出warning,最终索引创建成功,取前缀索引(取前255字节)。
下列情况下,Mysql不会使用已有的索引
1.如果mysql估计使用索引比全表扫描更慢,则不使用索引。
2.如果使用heap表并且where条件中不用=索引列,其他> 、<、 >=、 <=均不使用索引;
3.如果不是索引列的第一部分;
4.如果like是以%开始;
5.对where后边条件为字符串的一定要加引号,字符串如果为数字mysql会自动转为字符串,但是不使用索引。
查看索引使用情况
如果索引正在工作,Handler_read_key的值将很高,这个值代表了一个行被索引值读的次数,很低的值表明增加索引得到的性能改善不高,因为索引并不经常使用。
Handler_read_rnd_next的值高则意味着查询运行低效,并且应该建立索引补救。这个值的含义是在数据文件中读下一行的请求数。如果你正进行大量的表扫描,该值较高。通常说明表索引不正确或写入的查询没有利用索引。
语法:mysql> show status like 'Handler_read%';
针对索引的基本操作
创建索引
create index index_name on table(colum_name)
alter table talbe_name add index index_name(colum_name)
create table table_name(colum_name,index_name(colum_name))
删除索引
drop index index_name on table_name
alter table talbe_name drop index index_name
查看索引
show create table table_name
show index from table_name
针对建立普通索引和不建立普通索引执行语句时间对比测试
1、建立测试表
mysql> create table ab(id int,name varchar(20));
2、向表里插入10000000行记录,手动插入很不现实就需要写一个简单的存储过程进行向表中插入数据
mysql> create procedure ab_test ()
-> begin
-> declare i int default 1;
-> while i<10000000 do
-> insert into ab values(i,'bob');
-> set i=i+1;
-> end while;
-> end //
Query OK, 0 rows affected (0.00 sec)
3、在未建立索引的情况下对表进行查询
mysql> select * from ab where id=9999999
-> ;
+---------+------+
| id | name |
+---------+------+
| 9999999 | bob |
+---------+------+
1 row in set (3.89 sec) 友情提示:如果语句执行在10毫秒内是不会显示执行时间
没有建立索引查询使用389毫秒
4、建立索引的情况下进行查询
mysql> create index index_id on ab (id);
Query OK, 9999999 rows affected (39.92 sec)
Records: 9999999 Duplicates: 0 Warnings: 0
mysql> select * from ab where id=9999999;
+---------+------+
| id | name |
+---------+------+
| 9999999 | bob |
+---------+------+
1 row in set (0.22 sec)
使用了索引,进行查询使用22毫秒
对于建立前缀索引和普通索引的对比测试
在针对varchar和char字段属性建立普通索引花费很长时间
mysql> select * from ab where name='bob';
+---------+------+
| id | name |
+---------+------+
| 1000000 | bob |
+---------+------+
1 row in set (14.55 sec)没有建立索引的情况
mysql> create index ab_test on ab(name);
Query OK, 10000000 rows affected (24 min 14.48 sec) 使用时间为24分钟
Records: 10000000 Duplicates: 0 Warnings: 0
mysql> select * from ab where name='bob';
+---------+------+
| id | name |
+---------+------+
| 1000000 | bob |
+---------+------+
1 row in set (0.08 sec)
mysql> create index ab_test on ab(name(10));
Query OK, 10000000 rows affected (1 min 33.21 sec) 使用前缀添索引的速度比快23分钟
Records: 10000000 Duplicates: 0 Warnings: 0
mysql> select * from ab where name='bob';
+---------+------+
| id | name |
+---------+------+
| 1000000 | bob |
+---------+------+
1 row in set (0.35 sec) 但是查询的速度比上面慢
添加索引前缀一般是针对varchar和char,中字符很多的情况下