首页 > 数据库 >mysql 深入学习三 索引优化二 (索引下推、trace工具)

mysql 深入学习三 索引优化二 (索引下推、trace工具)

时间:2023-08-27 12:22:05浏览次数:50  
标签:index name trace employees 索引 range mysql position

使用上一篇的表并插入测试数据

#‐‐ 插入一些示例数据
drop procedure if exists insert_emp;
delimiter ;;
create procedure insert_emp()
    begin
    declare i int;
    set i=1;
    while(i<=100000)do
        insert into employees(name,age,position) values(CONCAT('zhuge',i),i,'dev');
        set i=i+1;
    end while;
end;;
delimiter ;
call insert_emp();

 

1.联合索引第一个字段用范围不会走索引

  结论:联合索引第一个字段就用范围查找不会走索引,mysql内部可能觉得第一个字段就用范围,结果集应该很大,回表效率不高,还不如就全表扫描 2.强制走索引

   实验:关于<查询缓存>请查看:https://tool.4xseo.com/a/11076.html

结论:虽然使用了强制走索引让联合索引第一个字段范围查找也走索引,扫描的行rows看上去也少了点,    但是最终查找效率不一定比全表扫描高,因为回表效率不高  3、对1进行覆盖索引优化  

 4、in和or在表数据量比较大的情况会走索引,在表记录不多的情况下会选择全表扫描

  1.表数据量大(走索引)   

   2.表数据量小(不走索引)《做一个小实验,将employees 表复制一张employees_copy1的表,里面保留两三条记录 》type列为 ALL

5、like KK% 一般情况都会走索引(LiLei% 用到了 ‘索引下推’)   1.表数据量大(会走索引)  

   2.表数据量小(会走索引) 

  索引下推(Index Condition Pushdown,ICP) 对于辅助的联合索引(name,age,position),正常情况按照最左前缀原则, SELECT * FROM employees WHERE name like 'LiLei%' AND age = 22 AND position ='manager'; 这种情况只会走name字段索引,因为根据name字段过滤完,得到的索引行里的age和position是无序的,无法很好的利用索引。   在MySQL5.6之前的版本,这个查询只能在联合索引里匹配到名字是 'LiLei' 开头的索引,然后拿这些索引对应的主键逐个回表, 到主键索引上找出相应的记录,再比对age和position这两个字段的值是否符合。   MySQL 5.6引入了索引下推优化,可以在索引遍历过程中,对索引中包含的所有字段先做判断过滤掉不符合条件的记录之后再回表, 可以有效的减少回表次数。 使用了索引下推优化后,上面那个查询在联合索引里匹配到名字是 'LiLei' 开头的索引之后,同时还会在索引里过滤age和position这两个字段, 拿着过滤完剩下的索引对应的主键id再回表查整行数据。 索引下推会减少回表次数,对于innodb引擎的表索引下推只能用于二级索引,innodb的主键索引(聚簇索引)树叶子节点上保存的是全行数据, 所以这个时候索引下推并不会起到减少查询全行数据的效果。   为什么范围查找Mysql没有用索引下推优化? 估计应该是Mysql认为范围查找过滤的结果集过大,like KK% 在绝大多数情况来看,过滤后的结果集比较小, 所以这里Mysql选择给 like KK% 用了索引下推优化,当然这也不是绝对的,有时like KK% 也不一定就会走索引下推。   Mysql如何选择合适的索引 

如果用name索引需要遍历name字段联合索引树,然后还需要根据遍历出来的主键值去主键索引树里再去查出最终数据,成本比全表扫描还高 可以用覆盖索引优化,这样只需要遍历name字段的联合索引树就能拿到所有结果,如下: 

  

对于上面这两种 name>'a' 和 name>'zzz' 的执行结果,mysql最终是否选择走索引或者一张表涉及多个索引,mysql最终如何选择索引? 我们可以用 trace工具来一查究竟,开启trace工具会影响mysql性能,所以只能临时分析sql使用,用完之后立即关闭   开启trace工具:SET SESSION optimizer_trace="enabled=on",end_markers_in_json=on; 

{
  "steps": [
    {
      "join_preparation": { /*第一阶段:SQL准备阶段,格式化sql*/
        "select#": 1,
        "steps": [
          {
            "expanded_query": "/* select#1 */ select `employees`.`id` AS `id`,`employees`.`name` AS `name`,`employees`.`age` AS `age`,`employees`.`position` AS `position`,`employees`.`hire_time` AS `hire_time` from `employees` where (`employees`.`name` > 'a') order by `employees`.`position`"
          }
        ] /* steps */
      } /* join_preparation */
    },
    {
      "join_optimization": { /*第二阶段:SQL优化阶段*/
        "select#": 1,
        "steps": [
          {
            "condition_processing": { /*条件处理*/
              "condition": "WHERE",
              "original_condition": "(`employees`.`name` > 'a')",
              "steps": [
                {
                  "transformation": "equality_propagation",
                  "resulting_condition": "(`employees`.`name` > 'a')"
                },
                {
                  "transformation": "constant_propagation",
                  "resulting_condition": "(`employees`.`name` > 'a')"
                },
                {
                  "transformation": "trivial_condition_removal",
                  "resulting_condition": "(`employees`.`name` > 'a')"
                }
              ] /* steps */
            } /* condition_processing */
          },
          {
            "substitute_generated_columns": {
            } /* substitute_generated_columns */
          },
          {
            "table_dependencies": [ /*表依赖*/
              {
                "table": "`employees`",
                "row_may_be_null": false,
                "map_bit": 0,
                "depends_on_map_bits": [
                ] /* depends_on_map_bits */
              }
            ] /* table_dependencies */
          },
          {
            "ref_optimizer_key_uses": [
            ] /* ref_optimizer_key_uses */
          },
          {
            "rows_estimation": [ /*预估表的访问成本*/
              {
                "table": "`employees`",
                "range_analysis": {
                  "table_scan": { /*全表扫描*/
                    "rows": 75954, /*扫描行数*/
                    "cost": 15482 /*查询成本*/
                  } /* table_scan */,
                  "potential_range_indexes": [ /*查询可能使用的索引*/
                    {
                      "index": "PRIMARY", /*主键索引*/
                      "usable": false,
                      "cause": "not_applicable"
                    },
                    {
                      "index": "idx_name_age_position", /*辅助索引*/
                      "usable": true,
                      "key_parts": [
                        "name",
                        "age",
                        "position",
                        "id"
                      ] /* key_parts */
                    }
                  ] /* potential_range_indexes */,
                  "setup_range_conditions": [
                  ] /* setup_range_conditions */,
                  "group_index_range": {
                    "chosen": false,
                    "cause": "not_group_by_or_distinct"
                  } /* group_index_range */,
                  "analyzing_range_alternatives": { /*分析各个索引使用成本*/
                    "range_scan_alternatives": [
                      {
                        "index": "idx_name_age_position",
                        "ranges": [
                          "a < name" /*索引使用范围*/
                        ] /* ranges */,
                        "index_dives_for_eq_ranges": true,
                        "rowid_ordered": false, /*使用该索引获取的记录是否按照主键排序*/
                        "using_mrr": false, 
                        "index_only": false, /*是否使用覆盖索引*/
                        "rows": 37977, /*索引扫描行数*/
                        "cost": 45573, /*索引使用成本*/
                        "chosen": false, /*是否选择该索引*/
                        "cause": "cost"
                      }
                    ] /* range_scan_alternatives */,
                    "analyzing_roworder_intersect": {
                      "usable": false,
                      "cause": "too_few_roworder_scans"
                    } /* analyzing_roworder_intersect */
                  } /* analyzing_range_alternatives */
                } /* range_analysis */
              }
            ] /* rows_estimation */
          },
          {
            "considered_execution_plans": [
              {
                "plan_prefix": [
                ] /* plan_prefix */,
                "table": "`employees`",
                "best_access_path": { /*最优访问路径*/
                  "considered_access_paths": [ /*最终选择的访问路径*/
                    {
                      "rows_to_scan": 75954,
                      "access_type": "scan", /*访问类型:为scan,全表扫描*/
                      "resulting_rows": 75954,
                      "cost": 15480,
                      "chosen": true, /*确定选择*/
                      "use_tmp_table": true
                    }
                  ] /* considered_access_paths */
                } /* best_access_path */,
                "condition_filtering_pct": 100,
                "rows_for_plan": 75954,
                "cost_for_plan": 15480,
                "sort_cost": 75954,
                "new_cost_for_plan": 91434,
                "chosen": true
              }
            ] /* considered_execution_plans */
          },
          {
            "attaching_conditions_to_tables": {
              "original_condition": "(`employees`.`name` > 'a')",
              "attached_conditions_computation": [
              ] /* attached_conditions_computation */,
              "attached_conditions_summary": [
                {
                  "table": "`employees`",
                  "attached": "(`employees`.`name` > 'a')"
                }
              ] /* attached_conditions_summary */
            } /* attaching_conditions_to_tables */
          },
          {
            "clause_processing": {
              "clause": "ORDER BY",
              "original_clause": "`employees`.`position`",
              "items": [
                {
                  "item": "`employees`.`position`"
                }
              ] /* items */,
              "resulting_clause_is_simple": true,
              "resulting_clause": "`employees`.`position`"
            } /* clause_processing */
          },
          {
            "reconsidering_access_paths_for_index_ordering": {
              "clause": "ORDER BY",
              "steps": [
              ] /* steps */,
              "index_order_summary": {
                "table": "`employees`",
                "index_provides_order": false,
                "order_direction": "undefined",
                "index": "unknown",
                "plan_changed": false
              } /* index_order_summary */
            } /* reconsidering_access_paths_for_index_ordering */
          },
          {
            "refine_plan": [
              {
                "table": "`employees`"
              }
            ] /* refine_plan */
          }
        ] /* steps */
      } /* join_optimization */
    },
    {
      "join_execution": { /*‐第三阶段:SQL执行阶段*/
        "select#": 1,
        "steps": [
          {
            "filesort_information": [
              {
                "direction": "asc",
                "table": "`employees`",
                "field": "position"
              }
            ] /* filesort_information */,
            "filesort_priority_queue_optimization": {
              "usable": false,
              "cause": "not applicable (no LIMIT)"
            } /* filesort_priority_queue_optimization */,
            "filesort_execution": [
            ] /* filesort_execution */,
            "filesort_summary": { /*文件排序信息*/
              "rows": 81684, /*预计扫描行数*/
              "examined_rows": 81684, /*参与排序的行*/
              "number_of_tmp_files": 24, /*使用临时文件的个数,这个值如果为0代表全部使用的sort_buffer内存排序,否则使用的磁盘文件排序*/
              "sort_buffer_size": 262056, /*‐排序缓存的大小,单位Byte*/
              "sort_mode": "<sort_key, packed_additional_fields>" /*排序方式,这里用的单路排序*/
            } /* filesort_summary */
          }
        ] /* steps */
      } /* join_execution */
    }
  ] /* steps */
}
trace1带注解

 

{
  "steps": [
    {
      "join_preparation": {
        "select#": 1,
        "steps": [
          {
            "expanded_query": "/* select#1 */ select `employees`.`id` AS `id`,`employees`.`name` AS `name`,`employees`.`age` AS `age`,`employees`.`position` AS `position`,`employees`.`hire_time` AS `hire_time` from `employees` where (`employees`.`name` > 'zzz') order by `employees`.`position`"
          }
        ] /* steps */
      } /* join_preparation */
    },
    {
      "join_optimization": {
        "select#": 1,
        "steps": [
          {
            "condition_processing": {
              "condition": "WHERE",
              "original_condition": "(`employees`.`name` > 'zzz')",
              "steps": [
                {
                  "transformation": "equality_propagation",
                  "resulting_condition": "(`employees`.`name` > 'zzz')"
                },
                {
                  "transformation": "constant_propagation",
                  "resulting_condition": "(`employees`.`name` > 'zzz')"
                },
                {
                  "transformation": "trivial_condition_removal",
                  "resulting_condition": "(`employees`.`name` > 'zzz')"
                }
              ] /* steps */
            } /* condition_processing */
          },
          {
            "substitute_generated_columns": {
            } /* substitute_generated_columns */
          },
          {
            "table_dependencies": [
              {
                "table": "`employees`",
                "row_may_be_null": false,
                "map_bit": 0,
                "depends_on_map_bits": [
                ] /* depends_on_map_bits */
              }
            ] /* table_dependencies */
          },
          {
            "ref_optimizer_key_uses": [
            ] /* ref_optimizer_key_uses */
          },
          {
            "rows_estimation": [
              {
                "table": "`employees`",
                "range_analysis": {
                  "table_scan": {
                    "rows": 75954,
                    "cost": 15482
                  } /* table_scan */,
                  "potential_range_indexes": [
                    {
                      "index": "PRIMARY",
                      "usable": false,
                      "cause": "not_applicable"
                    },
                    {
                      "index": "idx_name_age_position",
                      "usable": true,
                      "key_parts": [
                        "name",
                        "age",
                        "position",
                        "id"
                      ] /* key_parts */
                    }
                  ] /* potential_range_indexes */,
                  "setup_range_conditions": [
                  ] /* setup_range_conditions */,
                  "group_index_range": {
                    "chosen": false,
                    "cause": "not_group_by_or_distinct"
                  } /* group_index_range */,
                  "analyzing_range_alternatives": {
                    "range_scan_alternatives": [
                      {
                        "index": "idx_name_age_position",
                        "ranges": [
                          "zzz < name"
                        ] /* ranges */,
                        "index_dives_for_eq_ranges": true,
                        "rowid_ordered": false,
                        "using_mrr": false,
                        "index_only": false,
                        "rows": 1,
                        "cost": 2.21,
                        "chosen": true
                      }
                    ] /* range_scan_alternatives */,
                    "analyzing_roworder_intersect": {
                      "usable": false,
                      "cause": "too_few_roworder_scans"
                    } /* analyzing_roworder_intersect */
                  } /* analyzing_range_alternatives */,
                  "chosen_range_access_summary": {
                    "range_access_plan": {
                      "type": "range_scan",
                      "index": "idx_name_age_position",
                      "rows": 1,
                      "ranges": [
                        "zzz < name"
                      ] /* ranges */
                    } /* range_access_plan */,
                    "rows_for_plan": 1,
                    "cost_for_plan": 2.21,
                    "chosen": true
                  } /* chosen_range_access_summary */
                } /* range_analysis */
              }
            ] /* rows_estimation */
          },
          {
            "considered_execution_plans": [
              {
                "plan_prefix": [
                ] /* plan_prefix */,
                "table": "`employees`",
                "best_access_path": {
                  "considered_access_paths": [
                    {
                      "rows_to_scan": 1,
                      "access_type": "range",
                      "range_details": {
                        "used_index": "idx_name_age_position"
                      } /* range_details */,
                      "resulting_rows": 1,
                      "cost": 2.41,
                      "chosen": true,
                      "use_tmp_table": true
                    }
                  ] /* considered_access_paths */
                } /* best_access_path */,
                "condition_filtering_pct": 100,
                "rows_for_plan": 1,
                "cost_for_plan": 2.41,
                "sort_cost": 1,
                "new_cost_for_plan": 3.41,
                "chosen": true
              }
            ] /* considered_execution_plans */
          },
          {
            "attaching_conditions_to_tables": {
              "original_condition": "(`employees`.`name` > 'zzz')",
              "attached_conditions_computation": [
              ] /* attached_conditions_computation */,
              "attached_conditions_summary": [
                {
                  "table": "`employees`",
                  "attached": "(`employees`.`name` > 'zzz')"
                }
              ] /* attached_conditions_summary */
            } /* attaching_conditions_to_tables */
          },
          {
            "clause_processing": {
              "clause": "ORDER BY",
              "original_clause": "`employees`.`position`",
              "items": [
                {
                  "item": "`employees`.`position`"
                }
              ] /* items */,
              "resulting_clause_is_simple": true,
              "resulting_clause": "`employees`.`position`"
            } /* clause_processing */
          },
          {
            "reconsidering_access_paths_for_index_ordering": {
              "clause": "ORDER BY",
              "steps": [
              ] /* steps */,
              "index_order_summary": {
                "table": "`employees`",
                "index_provides_order": false,
                "order_direction": "undefined",
                "index": "idx_name_age_position",
                "plan_changed": false
              } /* index_order_summary */
            } /* reconsidering_access_paths_for_index_ordering */
          },
          {
            "refine_plan": [
              {
                "table": "`employees`",
                "pushed_index_condition": "(`employees`.`name` > 'zzz')",
                "table_condition_attached": null
              }
            ] /* refine_plan */
          }
        ] /* steps */
      } /* join_optimization */
    },
    {
      "join_execution": {
        "select#": 1,
        "steps": [
          {
            "filesort_information": [
              {
                "direction": "asc",
                "table": "`employees`",
                "field": "position"
              }
            ] /* filesort_information */,
            "filesort_priority_queue_optimization": {
              "usable": false,
              "cause": "not applicable (no LIMIT)"
            } /* filesort_priority_queue_optimization */,
            "filesort_execution": [
            ] /* filesort_execution */,
            "filesort_summary": {
              "rows": 0,
              "examined_rows": 0,
              "number_of_tmp_files": 0,
              "sort_buffer_size": 262056,
              "sort_mode": "<sort_key, packed_additional_fields>"
            } /* filesort_summary */
          }
        ] /* steps */
      } /* join_execution */
    }
  ] /* steps */
}
trace2 无注解

  关闭tace工具:SET SESSION optimizer_trace="enabled=off"; 

   结论:全表扫描的成本低于索引扫描,所以mysql最终选择全表扫描。 查看trace字段可知索引扫描的成本低于全表扫描,所以mysql最终选择索引扫描               

标签:index,name,trace,employees,索引,range,mysql,position
From: https://www.cnblogs.com/ruber/p/17659485.html

相关文章

  • mysql数据库连接密码的修改
    使用MySQL创建新连接时,密码是一个非常重要的组成部分。默认情况下,MySQL会生成一个随机的密码,该密码由一串随机的字符组成,包括数字、字母和其它特殊字符。在安装MySQL时,您可以选择使用自己的密码,也可以使用默认密码。默认密码是MySQL在安装时为root用户设置的密码。在许多情况下,建......
  • 【MySQL 8.0】新特性:函数索引
    (root@node01)>selectcount(*)fromcustomerwhereyear(c_since)=2020;+----------+|count(*)|+----------+|702|+----------+1rowinset(0.46sec)(root@node01)>explainselectcount(*)fromcustomerwhereyear(c_since)=2020;+----+-......
  • MySQL事务
    2023.8.261.事务的四大特性A原子性C一致性I隔离性D持久性2.会出现的问题脏读:读到了另一个事物中未提交的修改不可重复读:一个事务前后两次因为另一个事务做了修改或导致读到的数据不同幻读:一个事务前后两次因为另一个事务做了新增而读取到了......
  • MySQL.js用法
    mysql.js是一个用于连接MySQL数据库的JavaScript库。以下是一些常用的方法及其详细参数说明: 1.创建连接对象: ```javascriptconstmysql=require('mysql');constconnection=mysql.createConnection({ host:'localhost',//数据库地址 user:'root',//数据......
  • MySQL 8与复制可观察性
    许多老MySQLDBA都使用showreplicastatus中的seconds_behind_source来了解(异步)复制的状态和正确执行情况。不过,MySQL复制已经有了很大的发展,复制团队已经努力为MySQL的所有复制方式提供了大量有用的信息。例如,增加了并行复制、组复制......所有这些信息都是老的showreplica......
  • mysql中truncate表对auto_increment的影响
    在mysql中,如果对表执行truncate操作后,会重新设置auto_increment的值,比如:root@localhost(none)>useabce;Databasechangedroot@localhostabce>createtabletest(idintnotnullauto_incrementprimarykey,ageint);QueryOK,0rowsaffected(0.02sec)root@localho......
  • 【MySQL 8.0】新特性:ALTER TABLE … ALGORITHM=INSTANT
    MySQL8.0.29之前,在线DDL操作中即时添加列只能添加在表的最后一列MySQL8.0.29扩展了对ALTERTABLE…ALGORITHM=INSTANT的支持:用户可以在表的任何位置即时添加列、即时删除列、添加列时评估行大小限制(root@node01)>altertablecustomeraddcolumnc_commentvarcha......
  • rhel 7.3搭建MySQL 5.7.21(一主一从GTID半同步复制)
    文档课题:rhel7.3搭建MySQL5.7.21(一主一从GTID半同步复制)数据库:MySQL5.7.21系统:rhel7.3环境:角色 主机名 IP 操作系统 server_id MySQL安装包master mysql-leo-master 192.168.133.111 rhel7.3 1 Percona-Server-5.7.21-20-Linux.x86_64.ssl101.tar.gzslave mysql-leo-s......
  • mysql 深入学习三 索引优化一
    测试建表CREATETABLE`employees`(`id`int(11)NOTNULLAUTO_INCREMENT,`name`varchar(24)NOTNULLDEFAULT''COMMENT'姓名',`age`int(11)NOTNULLDEFAULT'0'COMMENT'年龄',`position`varchar(20)NOT......
  • 【MySQL 8.0】新特性:支持CHECK约束
    (root@node01)>createtablestudent(idintprimarykey,namevarchar(255),ageint,genderchar(1),scorefloat,constraintchk_agecheck(age>=18),constraintchk_scorecheck(score>=0andscore<=100));QueryOK,0rowsaffected(0.20......