MySQL索引
没有索引,可能会有什么问题
索引:提高数据库的性能,索引是物美价廉的东西了。不用加内存,不用改程序,不用调sql,只要执行正确的 create index ,查询速度就可能提高成百上千倍。但是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的,这些写操作,增加了大量的IO。所以它的价值,在于提高一个海量数据的检索速度
这里我们先姑且不谈什么是索引,我们先来看看没有索引会怎么样?有索引又会怎么样?
--产生随机字符串
delimiter $$
create function rand_string(n INT)
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);
表结构:
认识磁盘
MySQL与存储
MySQL 给用户提供存储服务,而存储的都是数据,数据在磁盘这个外设当中。磁盘是计算机中的一个机械设备,相比于计算机其他电子元件,磁盘效率是比较低的,在加上IO本身的特征,可以知道,如何提交效率,是 MySQL 的一个重要话题
研究一下磁盘
看看磁盘中一个盘片
MySQL与磁盘交互的基本单位
而 MySQL 作为一款应用软件,可以想象成一种特殊的文件系统。它有着更高的IO场景,所以,为了提高基本的IO效率, MySQL 进行IO的基本单位是 16KB (后面统一使用 InnoDB 存储引擎讲解)
也就是说,磁盘这个硬件设备的基本单位是512字节,而MySQL InnoDB引擎使用16kb与磁盘进行IO交互;即MySQL和磁盘进行数据交互的基本单位是16kb。这个基本数据单元,在MySQL这里叫做page(注意和OS系统的page区分);
可是按照我们对于计算机体系和计算机网络模型的理解,MySQL是属于一个应用层的程序,应用层的程序是不能够直接与磁盘这个硬件进行交互的,如果应用层程序想要与硬件进行交互,必须通过OS,也就是应用层程序通过与OS的直接交互来完成与硬件的间接交互,在Linux下一切皆文件!包括硬件,因此在OS系统内部会用一个struct file结构体来描述磁盘这个硬件,在这个每个struct file结构体都会有一个内核级的输入输出缓冲区,我们以前用的类似于write、read这样的接口本质上也就是将用户数据拷贝到目标文件对应的struct file中的缓冲区中,然后再由OS结合一定的刷新策略将缓冲区中的文件刷新到磁盘中去,这时候OS进行的工作才叫真正的IO;
为此在逻辑上我们认为MySQL服务是直接与磁盘进行交互的,但是实际上并不是的,实际上MySQL的16kb基本交互单位是与OS进行交互的,准确点来说就是与OS所维护的文件缓冲区进行交互,然后再由OS结合一定的策略将缓冲区中的数据刷新到磁盘,当然我们也可以利用系统调用fync(fd)来强制刷新文件缓冲区!强制OS将缓冲区中的数据刷新到磁盘:
MySQL服务、OS、磁盘的关系:
建立共识
索引的理解
理解单个Page
理解多个page
上面我们也说了每个page的大小是16kb,也就是说page是由大小上线的,那么也就意味着单个page
存储的数据量也是有上限的,现在要是我们插入大量数据的话,那么一个page肯定是不够的,我们需要多个page来存储这些大量数据:
可是这样的话,我们如果想要查某一条数据的话,那么我们就得一个page一个page的遍历,并且在每个page中又要进行页内遍历,时间时间复杂度比较高,效率低;
那么有没有什么办法来提高一下查询效率呢?