mysql学习五:索引
索引:由数据库中的一列或者多条组合而成,其作用是提高对表中数据的查询速度;类似于图书的目录,方便快速定位。
索引的优点:提高查询的速度;
缺点:创建和维护索引的时间增加了,但消耗不大;
索引的分类:
- 普通索:可以创建在任何数据类型中
- 唯一性索引:使用unique参数设置,在创建唯一索引时,该字段的值必须是唯一的
- 全文索引:使用fulltext参数设置;只有myisam引擎支持该索引;全文索引只能创建在char,varchar,text类型的字段上。主要作用就是提高查询较大字符串类型的速度
- 单列索引:单列索引,可以是普通索引,也可以是唯一索引,或全文索引
- 多列索引:是在表的多个字段上创建一个索引
- 空间索引:使用spatital参数可以设置空间索引;空间索引只能建立在空间数据类型上,这样可以提高系统获取空间数据的效率;只有myisam引擎支持
什么情况下添加索引?
- 该字段数据量比较大
- 该字段很少出现DML操作
- 该字段经常出现在where条件中
查看索引:
show index from 表名;
删除索引,使用drop或alter
drop index 索引名 on 表名; alter table table_name drop index index_name ; alter table table_name drop primary key ;
创建索引,使用create或alter:
create [unique|fulltext|spatital] index 索引名 on 表名 (字段名 [(长度)] [asc|desc]);
ALTER TABLE 表名 ADD 索引类型(unique,primary key,fulltext,index)[索引名](字段名)
一、创建索引:
1.在创建表的时侯创建索引:
create table 表名( 字段名 类型类型 [完整性约束条件], ..... [unique|fulltext|spatital] index|key [别名] (字段名 [(长度)] [asc|desc]) );
创建普通索引:
create table user1 (id int, userName varchar(20), password varchar(20), index (userName) );
创建唯一索引:
create table user2 (id int, userName varchar(20), password varchar(20), unique index (userName) );
给索引起别名:
create table user3 (id int, userName varchar(20), password varchar(20), unique index alias_username (userName) );
创建全文索引:
create table user4 (id int, userName varchar(20), password varchar(20), fulltext index alias_username (userName) );
创建多列索引:
create table user5 (id int, userName varchar(20), password varchar(20), index alias_username (userName, password) );
为了进一步榨取mysql的效率,就可以考虑建立组合索引,如将用户的NAME,CITY,AGE建到一个索引里:
# 将name的前12个字节和cig,age组成组合索引 alter table user add index index_name_city_age (name(12), city, age);
建表时,NAME长度为64,这里用12,是因为一般情况下名字的长度不会超过12,这样会加快索引查询速度,还会减少索引文件的大小,提高INSERT,UPDATE的更新速度。
如果分别给NAME,CITY,AGE建立单列索引,让该表有3个单列索引,查询时和组合索引的效率是大不一样的,甚至远远低于我们的组合索引。虽然分别建立了三个索引,但mysql只能用到其中的那个它认为似乎是最有效率的单列索引,另外两个是用不到的,也就是说还是一个全表扫描的过程。
对于以上组合索引,相当于三组索引:
name,city,age
name,city
name
为什么没有CITY,AGE等这样的组合索引呢?这是因为mysql组合索引“最左前缀”的结果。简单的理解就是只从最左边的开始组合,并不是只要包含这三列的查询都会用到该组合索引。也就是说name_city_age(NAME(12),CITY,AGE)从左到右进行索引,如果没有左前索引,mysql不会执行索引查询。
如果索引列长度过长,这种列索引时将会产生很大的索引文件,不便于操作,可以使用前缀索引方式进行索引,前缀索引应该控制在一个合适的点,控制在0.31黄金值即可(大于这个值就可以创建)。
SELECT COUNT(DISTINCT(LEFT(`title`,10)))/COUNT(*) FROM Arctic; -- 这个值大于0.31就可以创建前缀索引,Distinct去重复 ALTER TABLE `user` ADD INDEX `uname`(title(10)); -- 增加前缀索引SQL,将人名的索引建立在10,这样可以减少索引文件大小,加快索引查询速度
2.在已经存在的表上创建索引
create [unique|fulltext|spatital] index 索引名 on 表名 (字段名 [(长度)] [asc|desc]);
创建一个没有索引的表:
create table user6 (id int, userName varchar(20), password varchar(20) );
创建普通索引:
create index index_alias_username on user6(userName);
创建唯一性索引:
create unique index index_alias_username1 on user6(userName);
创建多列索引:
create index index_alias_username2 on user6(userName, password);
3.用alter table语句来创建索引
alter table 表名 add [unique|fulltext|spatital] index 索引名 (字段名 [(长度)] [asc|desc]);
create table user7 (id int, userName varchar(20), password varchar(20) );
创建普通索引:
alter table user7 add index index_alias_username (userName);
创建唯一性索引:
alter table user7 add unique index index_alias_username1 (userName);
创建多列索引:
alter table user7 add index index_alias_username2 (userName, password);
二、删除索引:
drop index 索引名on 表名;
drop index index_alias_username1 on user7;
三、
以下情形不会使用索引,应尽量避免
SELECT `sname` FROM `stu` WHERE `age`+10=30;-- 不会使用索引,因为所有索引列参与了计算 SELECT `sname` FROM `stu` WHERE LEFT(`date`,4) <1990; -- 不会使用索引,因为使用了函数运算,原理与上面相同 SELECT * FROM `houdunwang` WHERE `uname` LIKE'后盾%' -- 走索引 SELECT * FROM `houdunwang` WHERE `uname` LIKE "%后盾%" -- 不走索引 -- 正则表达式不使用索引 -- 字符串与数字比较不使用索引; CREATE TABLE `a` (`a` char(10)); EXPLAIN SELECT * FROM `a` WHERE `a`="1" -- 走索引 EXPLAIN SELECT * FROM `a` WHERE `a`=1 -- 不走索引 select * from dept where dname='xxx' or loc='xx' or deptno=45 除非or的左右都可以使用索引,否则不会使用索引 -- 如果mysql估计使用全表扫描要比使用索引快,则不使用索引
使用索引时,有一些技巧:
1.索引不会包含有NULL的列
只要列中包含有NULL值,都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此符合索引就是无效的。
2.使用短索引
对串列进行索引,如果可以就应该指定一个前缀长度。例如,如果有一个char(255)的列,如果在前10个或20个字符内,多数值是唯一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。
3.索引列排序
mysql查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作,尽量不要包含多个列的排序,如果需要最好给这些列建复合索引。
4.like语句操作
一般情况下不鼓励使用like操作,如果非使用不可,注意正确的使用方式。like ‘%aaa%’不会使用索引,而like ‘aaa%’可以使用索引。
5.不要在列上进行运算
6.不使用NOT IN 、<>、!=操作,但<,<=,=,>,>=,BETWEEN,IN是可以用到索引的
7.索引要建立在经常进行select操作的字段上。
这是因为,如果这些列很少用到,那么有无索引并不能明显改变查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
8.索引要建立在值比较唯一的字段上。
9.对于那些定义为text、image和bit数据类型的列不应该增加索引。因为这些列的数据量要么相当大,要么取值很少。
10.在where和join中出现的列需要建立索引。
11.where的查询条件里有不等号(where column != …),mysql将无法使用索引。
12.如果where字句的查询条件里使用了函数(如:where DAY(column)=…),mysql将无法使用索引。
13.在join操作中(需要从多个数据表提取数据时),mysql只有在主键和外键的数据类型相同时才能使用索引,否则及时建立了索引也不会使用。
posted on 2018-09-15 23:45 myworldworld 阅读(233) 评论(0) 收藏 举报