mysql基于成本的优化(1)---mysql进阶(四十一)

2023-02-02 00:00:00 索引 查询 数据 成本 区间

前面我们说了join查询原理,基本的是嵌套查询,这种不推荐,如果数据量庞大,因为内存是有限的,不能放下所有的数据,可能查询到后面的时候,前面的数据就从内存从释放,为了减少磁盘的查询次数,有了join buffer这个缓存区,专门放被驱动表的数据,用来匹配查询出来的驱动表数据是否符合,当然还是建议用索引来查询。

基于成本的优化

前面我们都说mysql优化器,每次查询数据库都会选择低成本的方式访问,那么成本是什么呢?这里主要分为两类

I/O成本:我们查询表存储引擎是mySIMA和InnoDB都是从磁盘上查询数据的,然后把磁盘上的数据加载到内存里在获取。磁盘到内存这个过程就是I/O成本。

CPU成本:读取及检测数据是否满足过滤条件,如果没有用到索引排序,这时候对结果集进行排序都是会耗费CPU成本。

对于mysql中,规定读取一个页的成本是1.0,读取或者检测一条记录是否复合搜索条件的成本是0.2。这两个数称为成本常量,后面会经常用到。(注意:这里不管需不需要检测搜索条件,成本都是0.2)

单表查询成本

我们还是用之前建的single_table来讲解,对于一个查询sql语句,mysql先会计算出小成本的查询方式,后执行所谓的【执行计划】,之后调用存储引擎提供的真正接口访问。

根据过滤条件,找到所有可以使用的索引。

计算全表扫描大家。

计算不同索引扫描代价。

找出低成本的进行执行计划。

下面我们来分析一下:

SELECT * FROM single_table WHERE

key1 IN ('a', 'b', 'c') AND

key2 > 10 AND key2 < 1000 AND

key3 > key2 AND

key_part1 LIKE '%hello%' AND

common_field = '123';

根据搜索条件,找出所有可能使用的索引

Key1 in a,b,c可以使用到key1索引,

Key2 >10 and key2 < 1000 可以使用到key2二级索引,

Key3>key2,没有比较常量,无索引,

Key_part1 因为%在前面,无索引,

Common_field本身就无索引。

这种查询中可能会用到的索引称为possible keys,为什么说可能用到因为后执行方法未必会执行这个索引,会采用性能好的。


计算全表查询

对于innoDB表来说,全表查询就是直接查询聚簇索引中的记录,依次和给定的过滤条件做一下比较,然后把符合的条件放入结果集。所以全表扫描的成本=磁盘I/O+CPU成本,为了计算这两个信息,我们需要什么呢,我们前面说了一个页的成本查询是1.0,一条记录的查询成本是0.2,所以我们现在需要知道:

当前表存了多少数据页。

当前表有多少行数据。

那这两个数据从哪来?总不能计算出来吧,那样太耗费性能,mysql维护了一系列的统计数据来提高性能,我们可以用命令查看,主要注意data_length和rows:

mysql> SHOW TABLE STATUS LIKE 'single_table'\G
*************************** 1. row ***************************
           Name: single_table
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 9693
 Avg_row_length: 163
    Data_length: 1589248
Max_data_length: 0
   Index_length: 2752512
      Data_free: 4194304
 Auto_increment: 10001
    Create_time: 2018-12-10 13:37:23
    Update_time: 2018-12-10 13:38:03
     Check_time: NULL
      Collation: utf8_general_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.01 sec)

相关文章