MySQL索引特性

初识索引:

——>索引:提高数据库的查询速度的东西。

——>索引不用加内存,不用改程序,不用调sql,只要执行正确的create index ,查询速度就可能提高成百上千倍

——>但是,是用一定代价换来的,查询速度的提高是以插入,更新,删除的速度为代价的,这些写操作,增加了大量的IO。

常见索引:

主键索引、唯一索引、普通索引、全文索引。

——>只看文字,或许大家并不能感受到索引的魅力所在,那么就举个例子来让大家感受一下吧:
举例:
先创建一个海量表,如下,然后再查询,去观察查询时间

--构建一个8000000条记录的数据 
--构建的海量表数据需要有差异性,所以使用存储过程来创建, 拷贝下面代码就可以了,暂时不用理解
-- 产生随机字符串 
delimiter $$
returns varchar(255) 
begin  
declare chars_str varchar(100) default   'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ'; 
declare return_str varchar(255) default ''; 
declare i int default 0; 
while i < n do    
set return_str
=concat(return_str,substring(chars_str,floor(1+rand()*52),1));   
set i = i + 1;   
end while;  
return return_str;  
end $$ 
delimiter ;
 
--产生随机数字 
delimiter $$ 
create function rand_num() 
returns int(5) 
begin  
declare i int default 0; 
set i = floor(10+rand()*500); 
return i; 
end $$ delimiter ;

--创建存储过程,向雇员表添加海量数据 
delimiter $$
create procedure insert_emp(in start int(10),in max_num int(10)) begin 
declare i int default 0;  
set autocommit = 0;   
repeat  set i = i + 1;  
insert into EMP values ((start+i) ,rand_string(6),'SALESMAN',0001,curdate(),2000,400,rand_num());  until i = max_num 
end repeat; 
commit; 
end $$ 
delimiter ;
 
-- 执行存储过程,添加8000000条记录 
call insert_emp(100001, 8000000);

查询员工编号为998877的员工:

select *from emp where empno=998877;

可以看到耗时4.93秒,这还是在本机一个人来操作,在实际项目中,如果放在公网中,假如同时有1000个人 并发查询,那很可能就死机。 

解决方法:创建索引

alter table EMP add index(empno);

换一个员工编号,测试看看查询时间,结果很快就可以出来:

select *from emp where empno=182973;

接下来,进入正题:

一、索引理论的基本原理

MySQL索引特性_第1张图片

索引之所以查询速度快,是因为索引会形成一颗二叉树,这种二分查找的思想,很快就可以找到多要查找的东西;

索引占内存,索引是以空间换取时间的一种手段

当添加一条记录,除了添加到表中,还要维护二叉树,速度有影响,但不大。

当我们添加一个索引,不能够解决所有查询问题,需要分别给字段建立索引;例如 select * from EMP where ename='abcdef'; 

二、创建索引

1.主键索引

A、创建主键索引的方式:
(1)创建表的时候,直接在字段名后面指定primary key

create table student(id int primary key,name varchar(32));

(2)在创建表的最后,指定某列或者几列为主键索引

create table student(id int,name varchar(32),primary key(id));

(3)创建完表之后再添加

create table student(id int,nanme varchar(32));
alter table student add primary key(id);

B、主键索引的特点:

1、一个表中,最多有一个主键索引,当然可以使符合主键

2、主键索引的效率高(主键不可重复)

3、创建主键索引的列,它的值不能为null,且不能重复

4、主键索引的列基本上是int 

2.唯一索引

A、创建唯一索引的方式

(1)创建表的时候,直接在字段名后面指定为unique key

create table student(id int primary,name varchar(32) unique key);

(2)在创建表的最后,指定某列或者几列为唯一键

create table student(id int primary ky,name varchar(32),unique key(name));

(3)创建完表之后,添加唯一键 

create table student(id int primary key,name varchar(32));
alter table student add unique key(name);

B、唯一索引的特点

1、一个表中,可以有多个唯一索引

2、查询效率高

3、如果在某一列建立唯一索引,必须保证这列不能有重复数据

4、如果一个唯一索引上指定not null,等价于主键索引 

3.普通索引

A、创建普通索引的方式

(1)在表的定义最后,指定某列为索引

create table user(ia int primary key,name varchar(32),email varchar(32),index(name));

(2)创建完之后添加某列为普通索引

create table user(id int primary key,name varchar(32),email varchar(32));
alter table user add index(name);

(3)创建一个索引名为idx_name 的索引

creat table student(id int primary key,name varchar(32),email varchar(32));
create index idx_name on  user(name);

B、普通索引的特点

一个表中可以有多个普通索引,普通索引在实际开发中用的比较多

如果某列需要创建索引,但是该列有重复的值,那么我们就应该使用普通索引 

4.全文索引

      当对文章字段或有大量文字的字段进行检索时,会使用到全文索引。MySQL提供全文索引机制,但是有要求,要求 表的存储引擎必须是MyISAM,而且默认的全文索引支持英文,不支持中文。如果对中文进行全文检索,可以使用 sphinx的中文版(coreseek)。

A、全文索引的创建

(1)在创建表的最后创建

create table articles(id int primary key,title varchar(200),body text,fulltext(title,body));

(2)创建完表之后创建 

create table articles(id int primary key,title varchar(200),body text);
alter table articles add fulltext(title,body);

注:如果可能,请尽量先创建表并插入所有数据后再创建全文索引,而不要在创建表时就直接创建全文索引,因为前者比后者的全文索引效率要高。

    插入数据的过程就省略了,你们自己想插入什么都可以,接下来,就要看如何使用这个全文索引了,大家都知道,模糊查询是用like这个关键字,例如:

select *from articles where body like '%查询字符串%';

那么,我们使用全文索引查询也是这个样子的吗,当然不是,如果使用上面的查询语句,虽然可以查询出数据,但是没有使用到全文索引,可以用explain来看一下是否使用到全文索引,explain语句:

explain select *from articles where body like '%查询字符串%'\G

在出来的数据中找到key:,为null的话就表示没有用到索引。 显然此时是为null的

MySQL索引特性_第2张图片

所以,我们必须使用特有的语法才能使用全文索引进行查询,如下:

select *from article where match(title,body) against ('查询字符串');

 然后再次explain就可以看到key处不为null。

注:

索引创建的原则:

1、比较频繁作为查询条件的字段应该创建索引

2、唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件

3、更新非常频繁的字段不适合作创建索引

4、不会出现在where子句中的字段不该创建索引

 三、查询索引

方法一:

show keys from 表名;

 MySQL索引特性_第3张图片

方法二:

show index from 表名;

方法三:信息比较简略

desc 表名;

 四、删除索引

第一种方法-删除主键索引: 

alter table 表名 drop primary; 

第二种方法-其他索引的删除:

 alter table 表名 drop index 索引名;

索引名就是show keys from 表名 中的 Key_name 字段

第三种方法: 

drop index 索引名 on 表名 

 

 

你可能感兴趣的:(MySQL)