1、定义
一个排序列表,列别中存储的是索引值和包含此值的数据所在行的物理地址
2、作用
①利用索引,数据库可以快速定位,大大加快查询速度
②数据表很大,或查询时需关联多个表时,使用索引也可以提高查询速度
③加快表与表之间的连接速度
④使用分组和排序时可以大大减少时间
⑤提高数据库恢复数据时的速度
3、缺点
①索引会占用额外的磁盘空间。inodb表数据文件本身也是索引,myisam索引和数据文件是分离的
②更新一个包含索引的表,要比更新一个没有索引表花费时间更多,更新值的同时也会更新索引
4、创建表时需考虑的因素
①关联程度:选好关联字段
②每个字段的长度
③设计合理的索引列
④表数据要控制在合理范围内,可以在牺牲一定性能的条件下满足需求。5秒以上考虑优化,10秒以上一般出问题。问题原因:缓存失效,缓存击穿;缓存雪崩
5、创建索引的原则
若有索引,数据库会先进行索引查询、定位数据,若使用不当索引,反而会增加数据库的负担
①主键、外键必须有索引(创建主键、外键后自动生成索引,无需额外声明)
②一个表超过了300行的记录必须要声明索引,否则数据库查询时会遍历表的所有数据,一条一条查询
③互相之间有关联的表,在关联字段上设置索引,唯一性太差的字段不适合创建索引
④更新太频繁的字段不适合做索引
⑤经常被where条件匹配的字段,尤其是表的数据较多的应该创建索引
⑥经常进行group by分组语句,order by排序语句的字段要创建索引
⑦索引字段越小越好,长文本字段不适合创建索引。太长会延长索引速度
6、索引类型
共用 | 查看表的索引show index from test; |
修改索引类型alter table test engine=memory; | |
btree索引 | 创建BTREE索引create index name_index on test (name); |
hash索引 | 创建hash索引 create index idx_hash_column on test (sex) using hash; |
7、创建索引的类型
表内创建 | 普通索引index name_index (name) ; |
唯一索引unique phone_index (phone); | |
全文索引fulltext notes_index (notes); | |
联合索引index union_index (name,address) | |
主键索引自带索引 | |
表外创建 | 普通索引 alter table member add index cardid_index (card_id); |
唯一索引 create unique index phone_index on member (phone); alter table member add unique address_index (address); | |
全文索引 create fulltext index notes_index on test2 (notes); alter table test3 add fulltext notes_index (notes); | |
联合索引 create index index_union on test4 (card_id,phone); | |
查看索引结构show index from member; | |
检测索引是否生效 explain select * from vip_member where phone=4589; explain select * from test4 where card_id=36 and phone=23456; | |
删除索引drop index notes_index on test3; |
(1)普通索引
index name_index (name) ;
(2)唯一索引(与unique关联)
原则:能在建表时创建好条件,尽量在创建表时约束好条件,不要建表完成后再添加
唯一索引与普通索引类似,唯一索引的每个值都是唯一,唯一索引允许空值,添加唯一键才会创建唯一索引,最好不要为空。not null unique
方法1:create unique index phone_index on member (phone);
方法2:alter table member add unique address_index (address);
方法3:unique phone_index (phone);
(3)主键索引
创建表的指定的主键就是索引,添加主键自动添加主键索引
主键:①值唯一
②一个表只有一个主键
③主键值不允许有空值
④创建主键自动主键索引
(4)全文索引
一般用于text列,适合模糊查询时使用,可以在一篇文章中检索文章信息
方法1:外部创建全文索引create fulltext index notes_index on test2 (notes);
方法2:内部创建全文索引fulltext notes_index (notes);
方法3:外部添加全文索引alter table test3 add fulltext notes_index (notes);
检测全文索引是否生效
(5)联合索引
指定一个索引名,一个索引名对应多个列名
创建联合索引create index index_union on test4 (card_id,phone);
注:查看联合索引explain select * from test4 where card_id=36 and phone=23456;
删除索引drop index notes_index on test3;
8、索引失效
若是联合索引,查询时必须按照创建时的顺序来
索引机制:默认找最短的索引键,最优索引选择
①联合索引:从左到右开始,不能跳过索引,否则索引失效
②范围查询:有可能右侧的索引会失效
③若索引是字符串但没加单引号,索引会失效
④使用or语句,索引一定失效。使用or语句作为条件,mysql无法同时使用多个索引
⑤使用where is null或where is not null索引有时失效
where is null数据的绝大多数都是空值,索引失效
where is not null数据的绝大多数不是空值,索引失效
⑥使用in或not in
in age 索引生效
not in age 索引失效
范围查找
范围查找索引失效
使用or语句索引失效
9、重点
现在一张表的查询速度是7.62秒,如何优化?
首先查缓存,看是否有缓存记录,是否直接访问后端数据库(缓存击穿)
再看索引,请求的列值不是默认的索引。解决方式:添加索引,explain看索引是否生效
10、实题
比如为某商场做一个会员卡的系统,这个系统有一个会员表,有下列字段:
会员编号INT (主键索引)
会员姓名 VARCHAR(10) (联合索引)
会员身份证号码INT(18) (唯一索引)
会员电话INT(11) (唯一索引)
会员住址 VARCHAR(50) (联合索引)
会员备注信息 TEXT (全文索引)
需求:1、先创建表vip_member
2、根据你的选择分别创建合适的索引