Mysql基础(五)索引

一、索引的体验

说起提高数据库性能,索引是最物美价廉的东西了,不用加内存,不用改程序,不用调sql,查询速度就可能提高百倍千倍

举例说明:

构建海量数据表【8000000】,对比与索引与无索引的区别

测试数据和表:

CREATE TABLE dept( /*部门表*/
deptno MEDIUMINT   UNSIGNED  NOT NULL  DEFAULT 0,
dname VARCHAR(20)  NOT NULL  DEFAULT "",
loc VARCHAR(13) NOT NULL DEFAULT ""
) ;

#创建表EMP雇员
CREATE TABLE emp
(empno  MEDIUMINT UNSIGNED  NOT NULL  DEFAULT 0, /*编号*/
ename VARCHAR(20) NOT NULL DEFAULT "", /*名字*/
job VARCHAR(9) NOT NULL DEFAULT "",/*工作*/
mgr MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,/*上级编号*/
hiredate DATE NOT NULL,/*入职时间*/
sal DECIMAL(7,2)  NOT NULL,/*薪水*/
comm DECIMAL(7,2) NOT NULL,/*红利*/
deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 /*部门编号*/
) ;

#工资级别表
CREATE TABLE salgrade
(
grade MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
losal DECIMAL(17,2)  NOT NULL,
hisal DECIMAL(17,2)  NOT NULL
);

#测试数据
INSERT INTO salgrade VALUES (1,700,1200);
INSERT INTO salgrade VALUES (2,1201,1400);
INSERT INTO salgrade VALUES (3,1401,2000);
INSERT INTO salgrade VALUES (4,2001,3000);
INSERT INTO salgrade VALUES (5,3001,9999);

delimiter $$

#创建一个函数,名字 rand_string,可以随机返回我指定的个数字符串
create function rand_string(n INT)
returns varchar(255) #该函数会返回一个字符串
begin
#定义了一个变量 chars_str, 类型  varchar(100)
#默认给 chars_str 初始值   'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ'
 declare chars_str varchar(100) default
   'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ'; 
 declare return_str varchar(255) default '';
 declare i int default 0; 
 while i < n do
    # concat 函数 : 连接函数mysql函数
   set return_str =concat(return_str,substring(chars_str,floor(1+rand()*52),1));
   set i = i + 1;
   end while;
  return return_str;
  end $$


 #这里我们又自定了一个函数,返回一个随机的部门号
create function rand_num( )
returns int(5)
begin
declare i int default 0;
set i = floor(10+rand()*500);
return i;
end $$

 #创建一个存储过程, 可以添加雇员
create procedure insert_emp(in start int(10),in max_num int(10))
begin
declare i int default 0;
#set autocommit =0 把autocommit设置成0
 #autocommit = 0 含义: 不要自动提交
 set autocommit = 0; #默认不提交sql语句
 repeat
 set i = i + 1;
 #通过前面写的函数随机产生字符串和部门编号,然后加入到emp表
 insert into emp values ((start+i) ,rand_string(6),'SALESMAN',0001,curdate(),2000,400,rand_num());
  until i = max_num
 end repeat;
 #commit整体提交所有sql语句,提高效率
   commit;
 end $$

 #添加8000000数据
call insert_emp(100001,8000000)$$

#命令结束符,再重新设置为;
delimiter ;


-- 创建索引
-- empno_index 表示索引名
-- emp(empno) 表示在emp表的empon字段上创建
create index empno_index on emp(empno)

-- 索引本身也会占用空间

-- 创建索引后查询的速度
select * from emp 
where empno = 1234568

-- 没有在ename创建索引时,查询速度还是很慢
select * from emp 
where ename = 'axJxCT'

二、索引介绍

1、为什么没有索引会慢?

假如有一张员工表(emp),在没有索引时,执行 select * from emp where id = 1,那么数据表就会进行一次全表扫描,一条一条的去比较查找,即使第一条就找到匹配的数据,但是不会立刻返回找到的数据,而是会继续往下找,因为不知道数据表中是否还会有匹配的数据,仍然进行全表扫描,这就导致查询速度很慢

2、使用索引为什么快?

当在 id 列上创建索引,那么 id 列就会形成一颗二叉树搜索树

索引的简单原理图:

3、索引的代价:

(1)磁盘占用

(2)对(update delete insert)语句的效率影响

三、索引类型

1、主键索引,主键自动的为主键索引(类型 primary key)

create table t1(
    -- 主键,同事也是索引,称为主键索引
	id int primary key,
    name varchar(32)
)

2、唯一索引(unique)

create table t2(
    -- id是唯一的,同时也是索引,称为unique索引
	id int unique,
    name varchar(32)
)

3、普通索引(index)

4、全文索引(fulltext)【使用于MyISAM】,开发中考虑使用:全文搜索 Solr 和ElasticSearch(ES)

四、索引的使用

1、添加索引

-- 方式一
create [unique] index index_name on table_name(col_name[(length)] [ASC | DESC],...)
--方式二
alter table table_name add index[index_name](index_col_name,...)

2、添加主键(索引)

alter table 表名 add primary key(列名)

3、删除索引

-- 方式一
drop index index_name on table_name
-- 方式二
alter table table_name drop index index_name

4、删除主键索引

alter table table_name drop primary key

5、查询索引

-- 方式一
show index from table_name
-- 方式二
show indexes from table_name
-- 方式三
show keys from table_name

测试代码:

-- 测试表
create table t25(
 id int,
 `name` varchar(32)
)

-- 查询表是否有索引
show indexes from t25

-- 添加索引
-- 方式一
-- 添加唯一索引
create unique index id_index on t25(id)
-- 添加普通索引
create index id_index on t25(id)
-- 方式二
-- 添加普通索引
alter table t25 add index id_index(id)

create table t26(
 id int,
 `name` varchar(32)
)
-- 添加主键索引
-- 方式一,在创建表是指定字段为 primary key 就是添加主键索引
-- 方式二
alter table t26 add primary key (id)

-- 删除索引
-- 方式一
drop index id_index on t25
-- 方式二
alter table t25 drop index id_index

-- 删除主键索引
-- 主键所用不用指定字段,一张表只有一个主键索引
alter table t26 drop primary key

show index from t26

-- 修改索引,先删除原先的索引,再添加新的索引

-- 查询索引
-- 方式一
show index from t25
-- 方式二
show indexes from t26
-- 方式三
show keys from t25
-- 方式四
desc t25

问题:

1、如何选择唯一索引和普通索引

  • 如果某列的值,是不会重复的,则有限考虑使用 unique 索引,否则使用普通索引

五、索引规则

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

select * from emp where empno = 1

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

select * from emp where sex = '男'

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

select * from emp where logincount = 1

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

posted @ 2022-09-01 16:46  花椒蛋炒饭  阅读(45)  评论(0编辑  收藏  举报