本篇文章给大家带来了关于mysql的相关知识,其中主要介绍了关于索引优化器工作原理的相关内容,其中包括了mysql server的组成,mysql优化器选择索引额原理以及sql成本分析,最后通过 select 查询总结整个查询过程,下面一起来看一下,希望对大家有帮助。
推荐学习:mysql视频教程
一、mysql 优化器是如何选择索引的下面我们来看这张表,sub_odr_id字段创建了相关的 2 个索引,根据我们前面所学我们建立一个primary key (id)自增主键索引,(log_id, sub_odr_id)设置为联合索引、唯一索引,两个时间create_time、update_time分别设置两个索引。
create table `***` ( `id` bigint(20) not null auto_increment comment '主键id', `log_id` varchar(32) not null comment '交易流水号', `odr_id` varchar(32) not null comment '父单号', `sub_odr_id` varchar(32) not null comment '子单号', `create_time` datetime(0) not null comment '创建时间', `create_by` varchar(32) not null comment ' 创建人', `update_time` datetime(0) not null default current_timestamp(0) on update current_timestamp(0) comment '更新时间', `update_by` varchar(32) not null comment '更新人', primary key (`id`) using btree, unique index `unq_log_subodr_id`(`log_id`, `sub_odr_id`) using btree, index `idx_odr_id`(`odr_id`) using btree, index `idx_sub_id`(`sub_odr_id`) using btree, index `idx_create_time`(`create_time`) using btree, index `idx_update_time`(`update_time`) using btree) engine = innodb auto_increment = 1 set = utf8 collate = utf8_general_ci comment = '分摊业务明细表' row_format = dynamic;
在查询字段 sub_odr_id 中,理论上可以使用三个相关的索引:unq_log_subodr_id、idx_sub_id,mysql优化器如何从这三个索引中进行选择?
在关系数据库中,b+树只是用于存储的数据结构。
如何使用它取决于数据库的优化器。优化器确定特定索引的选择,即执行计划。优化器的选择基于成本,成本越低,首选指数越高。
1、mysql数据库组成mysql数据库由server(服务器)层和engine(引擎)层组成。
serve层有sql分析器、sql优化器和sql执行器,负责sql语句的具体执行过程。
engine层负责存储特定数据,例如最常用的innodb存储引擎,以及用于在内存中存储临时结果集的temptable引擎。
sql优化器将分析所有可能的执行计划,并选择成本最低的执行。这个优化器被称为cbo(基于成本的优化器)。
2、mysql数据库成本计算在 mysql中,一条 sql 的计算成本计算,很好理解,就是访问数据库(数据库页、磁盘)+处理数据。
cpu成本,表示计算成本,例如索引键值的比较、记录值的比较和结果集的排序。这些操作都在服务器层完成
io成本,表示引擎级io的成本,mysql 8.0可以通过区分表的数据是否在内存中来分别计算读取内存io和磁盘io的成本。
cost = server cost + engine cost = cpu cost + io cost
mysql优化器认为,如果一段sql需要创建一个基于磁盘的临时表,那么此时的成本是最大的,是基于内存的临时表的20倍。比较索引键值和记录的成本很低,但如果要比较的记录很多,成本就会非常大。
mysql 优化器认为,从磁盘读取的开销是内存开销的 4 倍(成本不是一成不变的会根据硬件变化)。
二、mysql查询成本查看各成本的值,mysql优化器的工作原理,我们执行下面这行sql语句,分析执行过程,mysql 索引选择是基于 sql 执行成本
explain format=json select * from test.fork_business_detail f where f.sub_odr_id = ''
read_cost表示从innodb存储引擎读取的成本;
eval_cost表示服务器层的cpu成本;
prefix_cost表示sql的总成本;
data_read_per_join 表示读取记录中的字节总数。
{ query_block: { cost_info: { query_cost: 1.20 }, table: { access_type: ref, possible_keys: [ idx_sub_id ], key: idx_sub_id, used_key_parts: [ sub_odr_id ], key_length: 98, ref: [ const ], cost_info: { read_cost: 1.00, eval_cost: 0.20, prefix_cost: 1.20, data_read_per_join: 1k }, used_columns: [ id, log_id, odr_id, sub_odr_id, create_time, create_by, update_time, update_by ] } }}
三、select 执行过程如何提高mysql的查询性能?首先,您需要了解查询优化器进行sql处理的整个过程。select sql 的执行过程为例,如下图所示:
客户端向服务器发送select查询;服务器首先检查查询缓存。如果缓存被命中,存储在缓存中的结果将立即返回。否则,进入下一阶段;
服务器执行sql解析、预处理,查询优化器生成相应的执行计划;mysql根据优化器生成的执行计划调用存储引擎的api执行查询;结果将返回到客户端,并同时放入查询缓存。
推荐学习:mysql视频教程
以上就是深入理解mysql索引优化器工作原理的详细内容。