MySQL数据库SQL语句优化原理专题(一)
需求【MySQL数据库SQL语句优化原理专题(一)】有粉丝要求 , 想要我写一篇关于如何写出高效的SQL语句 , 在这里 , 我就分享一下 , 在MySQL数据库中 , 如何查看SQL语句的执行计划 , 和几种写高效SQL的案例 。
看SQL语句的执行计划想要知道自己写的sql语句是否最优 , 是否有性能问题 , 最直接的办法 , 就是看SQL语句的执行计划 , 下面先看一下如何获取SQL语句的执行计划 。
mysql> explain select a.* from t_test1 a,t_test2 b where a.k=b.k and b.k > 100;+----+-------------+-------+------------+-------+-------------------+------+---------+------------+------+----------+--------------------------+| id | select_type | table | partitions | type| possible_keys| key| key_len | ref| rows | filtered | Extra|+----+-------------+-------+------------+-------+-------------------+------+---------+------------+------+----------+--------------------------+|1 | SIMPLE| b| NULL| index | k_1,idx_sbtest1_k | k_1| 4| NULL|10 |100.00 | Using where; Using index ||1 | SIMPLE| a| NULL| ref| k_1,idx_sbtest1_k | k_1| 4| sbtest.b.k |1 |100.00 | NULL|+----+-------------+-------+------------+-------+-------------------+------+---------+------------+------+----------+--------------------------+2 rows in set, 1 warning (0.01 sec)或者通过客户端工具 , 例如HeidiSQL图形工具进行查看
文章插图
对于如何看执行计划 , 在这里就不详细讲解了 , 分享一个高清图片 , 图里讲得很明白 。
文章插图
left join优化要优化left join的sql语句 , 先了解一下没有任何索引的情况下 , left join的工作原理
文章插图
其实在没有任何索引的情况下 , left join使用的是Nested-Loop Join方式 , 原理是通过双层循环比较数据来获得结果 , 但是这种算法效率很低 , 举个例子 , 表t_test1中有有1000条数据 , 表t_test2中有100条记录 , 那么对数据比较的次数=1000 * 100=10万次 , 很显然这种查询效率会非常低 。
那怎么进行优化呢 , 通过上面的left join原理图 , 很快就能得出结论 , 减少查询表t_test2的次数 , 如何减少 , 当然是在表t_test2上的K列上创建一个索引 , 优化之后 , 其扫描结果如下所示 。
文章插图
这样left join就变成了Index Nested-Loop Join , 其优化思路为了减少内层表数据的匹配次数 。 有的朋友会问我 , 那表t_test1上K字段需要创建索引吗 , 除非是在where条件中用到了K字段 , 不然可以不用创建索引 。
in子查询优化很多时候 , 会用到in子查询 , 那在MySQL数据库中 , 如果用到了in的子查询 , 该如何优化 , 下面就来举个例子
mysql> explain select a.* from t_test1 a where a.k in (select b.k from t_test2 b where b.k>100);+----+-------------+-------+------------+-------+-------------------+------+---------+------------+------+----------+-------------------------------------+| id | select_type | table | partitions | type| possible_keys| key| key_len | ref| rows | filtered | Extra|+----+-------------+-------+------------+-------+-------------------+------+---------+------------+------+----------+-------------------------------------+|1 | SIMPLE| b| NULL| index | k_1,idx_sbtest1_k | k_1| 4| NULL|10 |100.00 | Using where; Using index; LooseScan ||1 | SIMPLE| a| NULL| ref| k_1,idx_sbtest1_k | k_1| 4| sbtest.b.k |1 |100.00 | NULL|+----+-------------+-------+------------+-------+-------------------+------+---------+------------+------+----------+-------------------------------------+2 rows in set, 1 warning (0.00 sec)从执行计划中可以看到 , in子查询也用到了索引 , 为什么会变成这样 , 是不是执行计划出错了 , MySQL数据库的优化器不会弄错的 , 我们用show warnings来揭晓答案 。
mysql> show warnings;+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Level | Code | Message|+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Note| 1003 | /* select#1 */ select `sbtest`.`a`.`id` AS `id`,`sbtest`.`a`.`k` AS `k`,`sbtest`.`a`.`c` AS `c`,`sbtest`.`a`.`pad` AS `pad` from `sbtest`.`t_test1` `a` semi join (`sbtest`.`t_test2` `b`) where ((`sbtest`.`a`.`k` = `sbtest`.`b`.`k`) and (`sbtest`.`b`.`k` > 100)) |+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+1 row in set (0.00 sec)
- pymysql 连接 MySQL 实现简单登录
- 巨杉亮相 DTCC2019,引领分布式数据库未来发展
- mysql 8.0.21 安装配置方法图文教程
- SpringBoot+MyBatis+MySQL读写分离实现
- Mysql不止CRUD,聊聊索引
- 详解mysql执行计划
- 什么是MySQL的执行计划(Explain关键字)?
- 数据库管理越来越复杂,有没有更简洁统一的解决方案?
- SQL竞争对手简史
- 中国数据库江湖风云录:阿里云从无到有“建高楼”
