mysql-sql优化和分析(EXPLAIN)

--  查询 员工
SELECT  *  FROM  `employees` WHERE NAME="LiLei"
--  查看sql是否使用索引,前面加上 EXPLAIN  即可

EXPLAIN  SELECT  *  FROM  `employees` WHERE NAME="LiLei"

 

expain中的列

expain出来的信息有10列,分别是id、select_type、table、partitions、type、possible_keys、key、key_len、ref、rows、Extra

1:id

  1. id列的编号是 select 的序列号,有几个 select 就有几个id.
  2. id的顺序是按 select 出现的顺序增长的。 id列越大执行优先级越高.
  3. id相同则从上往下执行,id为NULL最后执行。

2:select_type

  1. simple:简单查询。查询不包含子查询和union
  2. primary:复杂查询中最外层的 select
  3. subquery:包含在 select 中的子查询(不在 from 子句中)
  4. derived:包含在 from 子句中的子查询。MySQL会将结果存放在一个临时表中,也称为派生表
  5. union:在 union 中的第二个和随后的 select

3:table 

  1. 这一列表示 explain 的一行正在访问哪个表。

4:type

  1. 表示sql执行类型
  2. 依次从最优到最差分别为:system > const > eq_ref > ref > range > index > ALL
  3. 一般来说,得保证查询达到range级别,最好达到ref

 

 

5:possible_keys

  1. 这一列显示,可能使用那些索引来查找

6:key

  1. 这一列显示,采用哪个索引来查找

7:key_len

  1. 这一列显示。使用索引的字节
key_len计算规则如下:
 
      字符串,char(n)和varchar(n),5.0.3以后版本中, n均代表字符数,而不是字节数, 如果是utf-8,一个数字 或字母占1个字节,一个汉字占3个字节
 
  • char(n):如果存汉字长度就是 3n 字节
  • varchar(n):如果存汉字则长度是 3n + 2 字节,加的2字节用来存储字符串长度,因为 varchar是变长字符串
数值类型
  • tinyint:1字节
  • smallint:2字节
  • int:4字节
  • bigint:8字节
时间类型
  • date:3字节timestamp:4字节
  • datetime:8字节
    如果字段允许为 NULL,需要1字节记录是否为 NULL ,索引最大长度是768字节,当字符串过长时,mysql会做一个类似左前缀索引的处理,将前半部分的字符提取出来做索 引。

8:ref

9:rows

  1. 这一列是mysql估计要读取并检测的行数(不是结果集里的行数)

10:Extra

  1. Using index: 使用覆盖索引
  2. Using  where: 使用where来查询结果,并且查询的列没有被索引覆盖
  3. using index condition:搜索条件中虽然出现了索引列,但是有部分条件无法使用索引,会根据能用索引的条件先搜索一遍再匹配无法使用索引的条件。
  4. using temporary:创建临时表来处理查询,此时就需要优化
  5. Using filesort:将用外部排序而不是索引排序

 

 

优化避免

  1. 最左前缀,创建的联合索引,查询从最左前列开始,并且不跳过索引中的列
  2. 联合索引,如果第一个字段是范围查询,不会走索引
  3. 查询条件,不能再索引列上做任何操作(计算,函数,类型转换等),会导致索引失效
  4. 尽量使用覆盖索引(只查询是索引的列),减少select * 语句
  5. 关联表查询,尽量先查询数据少的表
  6. is null, is not null 一般无法用索引
  7. like, 通配符在左边的,索引会失效 '%abc',  通配符在右边  会走索引abc% (如果非使用like,最好使用覆盖索引)
  8. 字符串不加单引号,索引会失败
  9. 少用or 或者  in,  在数据少时不会用索引,数据多时会用索引(mysql内部优化器会判断,是否采用索引)

 

 

race

 

             mysql最终是否选择走索引或者一张表涉及多个索引,mysql最终如何选择索引,我们可以用trace工具 来一查究竟,开启trace工具会影响mysql性能,所以只能临时分析sql使用,用 完之后立即关闭
trace工具用法:
一:开启trace
SET OPTIMIZER_TRACE="enabled=on",END_MARKERS_IN_JSON=ON;
SET optimizer_trace_offset=-30, optimizer_trace_limit=30;

二:查看是否开启

SHOW VARIABLES LIKE 'optimizer_trace';

 

三:执行sql

SELECT * FROM employees WHERE NAME = 'LiLei'; 

四:查询trace

   SELECT * FROM information_schema.OPTIMIZER_TRACE

 

结果:

 

{
  "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` = 'LiLei') limit 0,1000"
          }
        ] /* steps */
      } /* join_preparation */
    },
    {
      "join_optimization": {
        "select#": 1,
        "steps": [
          {
            "condition_processing": {
              "condition": "WHERE",
              "original_condition": "(`employees`.`name` = 'LiLei')",
              "steps": [
                {
                  "transformation": "equality_propagation",
                  "resulting_condition": "(`employees`.`name` = 'LiLei')"
                },
                {
                  "transformation": "constant_propagation",
                  "resulting_condition": "(`employees`.`name` = 'LiLei')"
                },
                {
                  "transformation": "trivial_condition_removal",
                  "resulting_condition": "(`employees`.`name` = 'LiLei')"
                }
              ] /* 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": [
              {
                "table": "`employees`",
                "field": "name",
                "equals": "'LiLei'",
                "null_rejecting": false
              },
              {
                "table": "`employees`",
                "field": "name",
                "equals": "'LiLei'",
                "null_rejecting": false
              }
            ] /* ref_optimizer_key_uses */
          },
          {
            "rows_estimation": [
              {
                "table": "`employees`",
                "range_analysis": {
                  "table_scan": {
                    "rows": 199764,
                    "cost": 239719
                  } /* 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 */
                    },
                    {
                      "index": "name",
                      "usable": true,
                      "key_parts": [
                        "name",
                        "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": [
                          "LiLei <= name <= LiLei"
                        ] /* ranges */,
                        "index_dives_for_eq_ranges": true,
                        "rowid_ordered": false,
                        "using_mrr": false,
                        "index_only": false,
                        "rows": 2,
                        "cost": 3.41,
                        "chosen": true
                      },
                      {
                        "index": "name",
                        "ranges": [
                          "LiLei <= name <= LiLei"
                        ] /* ranges */,
                        "index_dives_for_eq_ranges": true,
                        "rowid_ordered": true,
                        "using_mrr": false,
                        "index_only": false,
                        "rows": 2,
                        "cost": 3.41,
                        "chosen": false,
                        "cause": "cost"
                      }
                    ] /* 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": 2,
                      "ranges": [
                        "LiLei <= name <= LiLei"
                      ] /* ranges */
                    } /* range_access_plan */,
                    "rows_for_plan": 2,
                    "cost_for_plan": 3.41,
                    "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": [
                    {
                      "access_type": "ref",
                      "index": "idx_name_age_position",
                      "rows": 2,
                      "cost": 2.4,
                      "chosen": true
                    },
                    {
                      "access_type": "ref",
                      "index": "name",
                      "rows": 2,
                      "cost": 2.4,
                      "chosen": false
                    },
                    {
                      "access_type": "range",
                      "range_details": {
                        "used_index": "idx_name_age_position"
                      } /* range_details */,
                      "chosen": false,
                      "cause": "heuristic_index_cheaper"
                    }
                  ] /* considered_access_paths */
                } /* best_access_path */,
                "condition_filtering_pct": 100,
                "rows_for_plan": 2,
                "cost_for_plan": 2.4,
                "chosen": true
              }
            ] /* considered_execution_plans */
          },
          {
            "attaching_conditions_to_tables": {
              "original_condition": "(`employees`.`name` = 'LiLei')",
              "attached_conditions_computation": [
              ] /* attached_conditions_computation */,
              "attached_conditions_summary": [
                {
                  "table": "`employees`",
                  "attached": null
                }
              ] /* attached_conditions_summary */
            } /* attaching_conditions_to_tables */
          },
          {
            "refine_plan": [
              {
                "table": "`employees`"
              }
            ] /* refine_plan */
          }
        ] /* steps */
      } /* join_optimization */
    },
    {
      "join_execution": {
        "select#": 1,
        "steps": [
        ] /* steps */
      } /* join_execution */
    }
  ] /* steps */
}

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值