MSQL系列(六) Mysql实战-SQL语句优化

这篇具有很好参考价值的文章主要介绍了MSQL系列(六) Mysql实战-SQL语句优化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Mysql实战-SQL语句优化

前面我们讲解了索引的存储结构,B+Tree的索引结构,以及索引最左侧匹配原则,Explain的用法,可以看到是否使用了索引,今天我们讲解一下SQL语句的优化及如何优化

1.表结构

新建表结构 user, user_info

#新建表结构 user
CREATE TABLE `user` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `id_card` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '身份证ID',
  `user_name` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户名字',
  `age` int NOT NULL COMMENT '年龄',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表'
  1. id 主键id列
  2. id_card 身份证id
  3. user_name 用户姓名
  4. age 年龄

先插入测试数据, 插入 5条测试数据

INSERT INTO `test`.`user` (`id`, `id_card`, `user_name`, `age`) VALUES (1, '11', 'aa', 10);
INSERT INTO `test`.`user` (`id`, `id_card`, `user_name`, `age`) VALUES (2, '22', 'bb', 20);
INSERT INTO `test`.`user` (`id`, `id_card`, `user_name`, `age`) VALUES (3, '33', 'cc', 30);
INSERT INTO `test`.`user` (`id`, `id_card`, `user_name`, `age`) VALUES (4, '44', 'dd', 40);
INSERT INTO `test`.`user` (`id`, `id_card`, `user_name`, `age`) VALUES (5, '55', 'ee', 50);
2 where语句及order的列 建立索引

表结构先不创建索引,我们看下执行分析
EXPLAIN SELECT * FROM user WHERE user_name=“AA”;

EXPLAIN SELECT * FROM `user` WHERE user_name="AA";

执行成功, type=ALL表示没有索引,查询效率低下
MSQL系列(六) Mysql实战-SQL语句优化,Mysql实战,mysql,Explain SQL优化,SQL语句分析优化,SQL分析,慢sql分析

我们在 user_name上建立索引后,再看下

#创建索引
alter  table `user` add index `idx_name`(`user_name`);

#执行分析
EXPLAIN SELECT * FROM `user` WHERE user_name="AA";

使用了索引,查询效率提升
MSQL系列(六) Mysql实战-SQL语句优化,Mysql实战,mysql,Explain SQL优化,SQL语句分析优化,SQL分析,慢sql分析

3. where语句不要使用!=,<>

where语句中使用!= 或者 <>, 或者使用 between and 都会是引擎放弃索引,进行全表扫描

我们新建 age的索引,然后基于age去做查询分析

#创建age索引
alter  table `user` add index `idx_age`(`age`);
#执行分析
EXPLAIN SELECT * FROM `user` WHERE age=10;

使用age索引进行查询,没有问题
MSQL系列(六) Mysql实战-SQL语句优化,Mysql实战,mysql,Explain SQL优化,SQL语句分析优化,SQL分析,慢sql分析
现在我们使用 != 或者 <> 来进行查询,执行查询分析

EXPLAIN SELECT * FROM `user` WHERE age !=10;
EXPLAIN SELECT * FROM `user` WHERE age <>10;
EXPLAIN SELECT * FROM `user` WHERE age BETWEEN 10 and 20;
EXPLAIN SELECT * FROM `user` WHERE age > 10 and age < 20 ;

执行结果全都是 type=range 表示在索引范围内查找,对索引的扫描开始于某一点,返回匹配值域的行, 已经不是ref类型了,效率已经不高了
Extra 其他信息= using index condition 表示会先条件过滤索引,过滤完索引后找到所有符合索引条件的数据行,随后用 WHERE 子句中的其他条件去过滤这些数据行;
using index condition = using index + 回表 + where 过滤
MSQL系列(六) Mysql实战-SQL语句优化,Mysql实战,mysql,Explain SQL优化,SQL语句分析优化,SQL分析,慢sql分析

4.where语句不要or进行判断

where语句使用or判断,也会导致引擎放弃索引,进而进行全表扫描
使用 or, 也会造成 type=range的情况

EXPLAIN SELECT * FROM `user` WHERE age =10 or age =20;

MSQL系列(六) Mysql实战-SQL语句优化,Mysql实战,mysql,Explain SQL优化,SQL语句分析优化,SQL分析,慢sql分析
这种情况,我们可以采用 union all 来进行优化

EXPLAIN SELECT * FROM `user` WHERE age =10 union all  SELECT * FROM `user` WHERE age =20 ;

MSQL系列(六) Mysql实战-SQL语句优化,Mysql实战,mysql,Explain SQL优化,SQL语句分析优化,SQL分析,慢sql分析

5.where语句不要使用 like模糊查询

like模糊查询,也会导致 全表扫描

#1.左侧开头精确匹配,右侧结果模糊
EXPLAIN SELECT * FROM `user` WHERE user_name like "a%";
#2.左侧开头模糊,右侧结果精确匹配
EXPLAIN SELECT * FROM `user` WHERE user_name like "%a";
#3.左侧开头模糊,右侧结果模糊
EXPLAIN SELECT * FROM `user` WHERE user_name like "%a%";

上面3种情况,我们来逐一分析

  1. 左侧开头精确匹配,右侧结果模糊, 查询会使用左侧索引进行匹配,type=range
EXPLAIN SELECT * FROM `user` WHERE user_name like "a%";

MSQL系列(六) Mysql实战-SQL语句优化,Mysql实战,mysql,Explain SQL优化,SQL语句分析优化,SQL分析,慢sql分析
2. 左侧开头模糊,右侧结果精确匹配, 查询不会使用索引,全表扫描 type=ALL

EXPLAIN SELECT * FROM `user` WHERE user_name like "%a";

MSQL系列(六) Mysql实战-SQL语句优化,Mysql实战,mysql,Explain SQL优化,SQL语句分析优化,SQL分析,慢sql分析
3. 左侧开头模糊,右侧结果模糊, 查询不会使用索引,全表扫描 type=ALL

EXPLAIN SELECT * FROM `user` WHERE user_name like "%a%";

MSQL系列(六) Mysql实战-SQL语句优化,Mysql实战,mysql,Explain SQL优化,SQL语句分析优化,SQL分析,慢sql分析

6.where语句 不要 in 和not in, 可能也会导致全表扫描

where子语句,使用 in,not in 也有可能导致全表扫描

所以使用in 到底走不走索引呢?

  • in通常是走索引的
  • IN 的条件过多,会导致索引失效,走索引扫描
  • 当in后面的数据在数据表中超过一定的数量 (有人说是30%,假如上面的例子的全部数据大约100条,匹配数据超过30条 ),会走全表扫描,即不走索引
  • in走不走索引和后面的数据有关系,这个比例不准

我表中5条数据, 我现在 in(10,20,30,40), in了4条,但是依旧走了索引 type=range, key=idx_age

EXPLAIN SELECT * FROM `user` WHERE age in(10,20,30,40);

MSQL系列(六) Mysql实战-SQL语句优化,Mysql实战,mysql,Explain SQL优化,SQL语句分析优化,SQL分析,慢sql分析

我现在再加一个in条件 in(10,20,30,40,50), 此刻就没有走索引, type=ALL

EXPLAIN SELECT * FROM `user` WHERE age in(10,20,30,40,50);

MSQL系列(六) Mysql实战-SQL语句优化,Mysql实战,mysql,Explain SQL优化,SQL语句分析优化,SQL分析,慢sql分析

但是 not in 是肯定不走索引的,这是我们明确禁止的

EXPLAIN SELECT * FROM `user` WHERE age not in(1,2);

MSQL系列(六) Mysql实战-SQL语句优化,Mysql实战,mysql,Explain SQL优化,SQL语句分析优化,SQL分析,慢sql分析

7.where语句不要使用表达式计算及函数运算

where子句,不要使用表达式计算或者函数运算,这回导致全表扫描

EXPLAIN SELECT * FROM `user` WHERE age / 2 =10;
EXPLAIN SELECT * FROM `user` WHERE SUBSTRING(user_name,1,3)="aa";

执行结果全部都是 type=ALL,使用表达式计算和函数的 都不会使用索引
MSQL系列(六) Mysql实战-SQL语句优化,Mysql实战,mysql,Explain SQL优化,SQL语句分析优化,SQL分析,慢sql分析


至此,我们了解如何去优化查询语句,在平时项目中,也应该多注意这些用法,防止出现线上事故文章来源地址https://www.toymoban.com/news/detail-722365.html

到了这里,关于MSQL系列(六) Mysql实战-SQL语句优化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • MSQL系列(十二) Mysql实战-为什么索引要建立在被驱动表上

    MSQL系列(十二) Mysql实战-为什么索引要建立在被驱动表上

    Mysql实战-为什么索引要建立在被驱动表上 前面我们讲解了B+Tree的索引结构,也详细讲解下 left Join的底层驱动表 选择原理,那么今天我们来看看到底如何用以及如何建立索引和索引优化 开始之前我们先提一个问题, 为什么索引要建立在被驱动表上 ? 1.建表及测试数据 我们先

    2024年02月08日
    浏览(25)
  • MySQL索引3——Explain关键字和索引优化(SQL提示、索引失效、索引使用规则)

    MySQL索引3——Explain关键字和索引优化(SQL提示、索引失效、索引使用规则)

    目录 Explain 索引性能分析 Id ——select的查询序列号 Select_type——select查询的类型 Table——表名称 Type——select的连接类型 Possible_key ——显示可能应用在这张表的索引 Key——实际用到的索引 Key_len——实际索引使用到的字节数 Ref    ——索引命中的列或常量 Rows——预

    2024年02月14日
    浏览(27)
  • [MySQL]SQL优化之sql语句优化

    [MySQL]SQL优化之sql语句优化

    🌈键盘敲烂,年薪30万🌈 目录 一、索引优化 回顾: 📕索引分类: 📕索引失效: 📕设计原则: 📕SQL性能分析 二、SQL优化 语句优化 📕 insert语句: 📕 主键优化: 📕 order by优化: 📕 group by优化: 📕 limit 优化 📕 count 优化 📕 update 优化  📕索引分类: 一般分类:主

    2024年02月04日
    浏览(11)
  • MySQL 参考文档:SQL 语句优化(SELECT 语句优化)之索引条件下推(索引下推)优化

    索引下推优化官方文档说明 (Section 8.2.1.5):https://dev.mysql.com/doc/refman/5.7/en/index-condition-pushdown-optimization.html 1. 什么是索引下推? qquad 索引条件下推 (Index Condition Pushdown,ICP) 是 MySQL 在使用索引从表中检索行时的一种优化方法。在没有 ICP 的情况下,存储引擎遍历索引以定位基

    2024年02月16日
    浏览(15)
  • MySQL性能优化之(explain)工具

    MySQL性能优化之(explain)工具

    在MySQL当中,我们有时候写的SQL执行效率太慢此时我们需要将其优化。但是SQL可能非常的多,难道我们一条一条的进行查看吗?在MySQL当当中我们可以查看慢查询日志,看看那些SQL这么慢。但是这个默认情况下这个慢查询日志是关闭的,我们可以通过一下命令进行查看 执行结

    2024年02月02日
    浏览(14)
  • MYSQL实战45讲笔记--基础架构:一条SQL查询语句是如何执行的?

    MYSQL实战45讲笔记--基础架构:一条SQL查询语句是如何执行的?

    MySQL 可以分为 Server 层和存储引擎层两部分。 Server 层 :连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等

    2024年02月07日
    浏览(11)
  • MySQL实战:SQL优化及问题排查

    MySQL实战:SQL优化及问题排查

    MySQL在选取索引时,会参考索引的基数,基数是MySQL估算的,反映这个字段有多少种取值,估算的策略为选取几个页算出取值的平均值,再乘以页数,即为基数 查看索引基数 使用force index可以强制使用索引 重新统计索引信息,会重新计算索引的基数 count(非索引字段):无法使

    2024年03月10日
    浏览(9)
  • MySql 性能优化神器之 explain 详解

    MySql 性能优化神器之 explain 详解

    目录 一. 前言 二. explain 详解 2.1. 概念 2.2. 数据准备 2.3. id 2.3.1. id 相同,执行顺序由上至下 2.3.2. id 不同,数字越大优先级越高 2.3.3. id 存在相同的和不同的 2.4. select_type 2.5. table 2.6. partitions 2.7. type 2.7.1. system 2.7.2. const 2.7.3. eq_ref 2.7.4. ref 2.7.5. fulltext 2.7.6. ref_or_null 2.7.7. 

    2024年02月03日
    浏览(13)
  • Mysql 学习(十 二)查询优化 Explain

    Mysql 学习(十 二)查询优化 Explain

    一条查询语句经过Mysql查询优化器的各种基于成本和规则的优化后生成一个所谓的执行计划,而Explain 语句可以让我们知道执行计划的语法,从而我们有针对性的提升性能 举例子: EXPLAIN SELECT 1 由此我们得到了一些参数,而这些参数我们可以知道我们这个执行计划做了那些优

    2024年02月05日
    浏览(21)
  • 【MYSQL高级】Mysql的SQL性能分析【借助EXPLAIN分析】

    【MYSQL高级】Mysql的SQL性能分析【借助EXPLAIN分析】

    要说sql有问题,需要拿出证据,因此需要性能分析 Mysql中有专门负责优化SELECT语句的优化器模块,主要功能:通过计算分析系统中收集到的统计信息,为客户端请求的Query提供他认为最优的执行计划(它认为最优的数据检索方式,不见得是DBA认为是最优的,这部分最耗费时间,

    2024年02月15日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包