大家好,我是知数堂SQL 优化班老师 网名:骑龟的兔子

今天给大家看一个案例来讨论,这个案例是真实案例,因为之前踩bug

导致数据库crash 所以临时关了优化器参数

set gloabl optimizer_switch='materialization=off';

这也是可以写一篇很长的文章,但是以后再说。

上面参数是控制 semi join 的几种方式的一种方式。

但是因为更改了上面的参数,导致的结果就是本来线上运行的很好的一个SQL运行了很长时间也运行不出来,然后我分析之后发现了一个之前讲课的时候不一样的东西,所以在这里分享。

materialization 这个参数简单来说是一个对于in

版本升级之后可以对 exists 产生作用

如下所示 有点类似于产生临时表然后可以生成临时索引

root@mysql3306.sock>[employees]>desc select   * from employees d   where  d.emp_no in ( select /*+ QB_NAME(sub1) */   t.emp_no  from dept_emp t ) ;
+----+--------------+-------------+------------+--------+---------------------+---------------------+---------+--------------------+--------+----------+-------------+
| id | select_type  | table       | partitions | type   | possible_keys       | key                 | key_len | ref                | rows   | filtered | Extra       |
+----+--------------+-------------+------------+--------+---------------------+---------------------+---------+--------------------+--------+----------+-------------+
|  1 | SIMPLE       | d           | NULL       | ALL    | PRIMARY             | NULL                | NULL    | NULL               | 298980 |   100.00 | NULL        |
|  1 | SIMPLE       | <subquery2> | NULL       | eq_ref | <auto_distinct_key> | <auto_distinct_key> | 4       | employees.d.emp_no |      1 |   100.00 | NULL        |
|  2 | MATERIALIZED | t           | NULL       | index  | PRIMARY,emp_no      | emp_no              | 4       | NULL               | 331143 |   100.00 | Using index |
+----+--------------+-------------+------------+--------+---------------------+---------------------+---------+--------------------+--------+----------+-------------+root@mysql3306.sock>[employees]>desc select  * from dept_emp d where   d.emp_no in (select t.emp_no  from t_group t ) ;
+----+--------------+-------------+------------+------+----------------+---------+---------+--------------------+------+----------+-------+
| id | select_type  | table       | partitions | type | possible_keys  | key     | key_len | ref                | rows | filtered | Extra |
+----+--------------+-------------+------------+------+----------------+---------+---------+--------------------+------+----------+-------+
|  1 | SIMPLE       | <subquery2> | NULL       | ALL  | NULL           | NULL    | NULL    | NULL               | NULL |   100.00 | NULL  |
|  1 | SIMPLE       | d           | NULL       | ref  | PRIMARY,emp_no | PRIMARY | 4       | <subquery2>.emp_no |    1 |   100.00 | NULL  |
|  2 | MATERIALIZED | t           | NULL       | ALL  | NULL           | NULL    | NULL    | NULL               |   10 |   100.00 | NULL  |
+----+--------------+-------------+------------+------+----------------+---------+---------+--------------------+------+----------+-------+

上面的内容在课上已经详细细说,他的优缺点和运用方法,在这里不细说

现在开始说的是最新发现的内容

有一种SQL如果是下面所展示 效果也不错

root@mysql3306.sock>[employees]>set session optimizer_switch='materialization=on';
Query OK, 0 rows affected (0.00 sec)root@mysql3306.sock>[employees]>desc select straight_join  * from dept_emp d where   d.emp_no in (select t.emp_no  from t_group t ) ;
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
|  1 | PRIMARY     | d     | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 331143 |   100.00 | Using where |
|  2 | SUBQUERY    | t     | NULL       | ALL  | NULL          | NULL | NULL    | NULL |     10 |   100.00 | NULL        |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+root@mysql3306.sock>[employees]>select straight_join  * from dept_emp d where   d.emp_no in (select t.emp_no  from t_group t ) ;
+--------+---------+------------+------------+
| emp_no | dept_no | from_date  | to_date    |
+--------+---------+------------+------------+
|  10004 | d004    | 1986-12-01 | 9999-01-01 |
|22744| d006    |1986-12-01| 9999-01-01 |
|  24007 | d005    | 1986-12-01 | 9999-01-01 |
|30970| d005    |1986-12-01| 9999-01-01 |
|  31112 | d002    | 1986-12-01 | 1993-12-10 |
|40983| d005    |1986-12-01| 9999-01-01 |
|  46554 | d008    | 1986-12-01 | 1992-05-27 |
|48317| d004    |1989-01-11| 9999-01-01 |
|  48317 | d008    | 1986-12-01 | 1989-01-11 |
|49667| d007    |1986-12-01| 9999-01-01 |
|  50449 | d005    | 1986-12-01 | 9999-01-01 |
+--------+---------+------------+------------+
11 rows in set (0.24 sec)

在这种情况执行由于种种原因我们把参数关了 那就会产生悲剧事件

root@mysql3306.sock>[employees]>set session optimizer_switch='materialization=off';
Query OK, 0 rows affected (0.00 sec)root@mysql3306.sock>[employees]>desc select straight_join  * from dept_emp d where   d.emp_no in (select t.emp_no  from t_group t ) ;
+----+--------------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type        | table | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra       |
+----+--------------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
|1| PRIMARY            | d     | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 331143 |100.00| Using where |
|  2 | DEPENDENT SUBQUERY | t     | NULL       | ALL  | NULL          | NULL | NULL    | NULL |     10 |    10.00 | Using where |
+----+--------------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)root@mysql3306.sock>[employees]>select straight_join  * from dept_emp d where   d.emp_no in (select t.emp_no  from t_group t ) ;
+--------+---------+------------+------------+
| emp_no | dept_no | from_date  | to_date    |
+--------+---------+------------+------------+
|  10004 | d004    | 1986-12-01 | 9999-01-01 |
|22744| d006    |1986-12-01| 9999-01-01 |
|  24007 | d005    | 1986-12-01 | 9999-01-01 |
|30970| d005    |1986-12-01| 9999-01-01 |
|  31112 | d002    | 1986-12-01 | 1993-12-10 |
|40983| d005    |1986-12-01| 9999-01-01 |
|  46554 | d008    | 1986-12-01 | 1992-05-27 |
|48317| d004    |1989-01-11| 9999-01-01 |
|  48317 | d008    | 1986-12-01 | 1989-01-11 |
|49667| d007    |1986-12-01| 9999-01-01 |
|  50449 | d005    | 1986-12-01 | 9999-01-01 |
+--------+---------+------------+------------+
11 rows in set (2.81 sec)

运行效果如上所示性能大幅度下降

这里的重要发现是我们之前所说的materialization 这个参数竟然还可以控制  SUBQUERY

那这种情况下 怎么弄可以优化呢

如果生成索引 性能可以恢复

root@mysql3306.sock>[employees]>create index idx_t_group_emp_no on t_group(emp_no);
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0root@mysql3306.sock>[employees]>desc select straight_join  * from dept_emp d where   d.emp_no in (select t.emp_no  from t_group t ) ;
+----+--------------------+-------+------------+----------------+--------------------+--------------------+---------+------+--------+----------+-------------+
| id | select_type        | table | partitions | type           | possible_keys      | key                | key_len | ref  | rows   | filtered | Extra       |
+----+--------------------+-------+------------+----------------+--------------------+--------------------+---------+------+--------+----------+-------------+
|1| PRIMARY            | d     | NULL       | ALL            | NULL               | NULL               | NULL    | NULL | 331143 |100.00| Using where |
|  2 | DEPENDENT SUBQUERY | t     | NULL       | index_subquery | idx_t_group_emp_no | idx_t_group_emp_no | 4       | func |      1 |   100.00 | Using index |
+----+--------------------+-------+------------+----------------+--------------------+--------------------+---------+------+--------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)root@mysql3306.sock>[employees]>select straight_join  * from dept_emp d where exists (select t.emp_no  from t_group t where t.emp_no=d.emp_no ) ;
+--------+---------+------------+------------+
| emp_no | dept_no | from_date  | to_date    |
+--------+---------+------------+------------+
|  10004 | d004    | 1986-12-01 | 9999-01-01 |
|22744| d006    |1986-12-01| 9999-01-01 |
|  24007 | d005    | 1986-12-01 | 9999-01-01 |
|30970| d005    |1986-12-01| 9999-01-01 |
|  31112 | d002    | 1986-12-01 | 1993-12-10 |
|40983| d005    |1986-12-01| 9999-01-01 |
|  46554 | d008    | 1986-12-01 | 1992-05-27 |
|48317| d004    |1989-01-11| 9999-01-01 |
|  48317 | d008    | 1986-12-01 | 1989-01-11 |
|49667| d007    |1986-12-01| 9999-01-01 |
|  50449 | d005    | 1986-12-01 | 9999-01-01 |
+--------+---------+------------+------------+
11 rows in set (0.84 sec)

index_subquery

This join type is similar to unique_subquery. It replaces IN subqueries, but it works for nonunique indexes in subqueries of the following form:

value IN (SELECT key_column FROM single_table WHERE some_expr)

这就本文想说的所有内容

materialization  这个参数实际运维过程中,一些稀奇古怪的数据不对的,甚至宕机的现象 也有可能跟这个参数有关,但是知悉分析之后可以发下还是SQL 写的有问题,可以通过修改SQL 形式绕开,大家多留意一下

P.S,松华老师遇到的Bug截图见下:

官方的回复,建议升级到最新版本,目前是8.0.27。此外,强烈建议至少升级到8.0.20之后,在此之前的版本某公有云上遇到非常多的问题。

我是知数堂SQL 优化班老师~ ^^

最新一期SQL优化课,在12月份开始。

如有关于SQL优化方面疑问和一起交流的请加 并且 @兔子@知数堂SQL优化

高性能MySQL,SQL优化群 有叶金荣,吴炳锡 两位大神坐镇 :579036588

欢迎加入 知数堂大家庭。

我的微信公众号:SQL开发与优化(sqlturning)

《实战MGR》视频课程

戳此小程序即可直达B站或腾讯课堂

或复制链接在浏览器中打开

  • https://ke.qq.com/course/3677969

  • https://space.bilibili.com/1363850082


文章推荐:

  • 面向金融级应用的GreatSQL正式开源

  • Changes in GreatSQL 8.0.25 (2021-8-26)

  • GreatSQL重磅特性,InnoDB并行查询优化测试

  • MySQL DDL简析(1):inplace DDL 主要stage介绍

  • Percona XtraBackup 8.0.26实战大全

  • 一条sql语句慢在哪之抓包分析

  • 技术分享 | Update更新慢、死锁等问题的排查思路分享

  • GreatSQL重磅特性,InnoDB并行并行查询优化测试

  • 在Linux下源码编译安装GreatSQL/MySQL


点击文末“阅读原文”直达老叶专栏

MySQL SQL 优化参数 引发的悲剧相关推荐

  1. mysql sql优化书籍_MySQL SQL优化的正确姿势

    大家好,我是知数堂SQL 优化班老师 网名:骑龟的兔子 已经很久没写文章了 今天分享一篇优化SQL 案例 slow query 里有如下 SQL 看下执行计划如下 从执行计划可以看出C表全表扫描了 那 ...

  2. MySQL SQL优化

    前言 有人反馈之前几篇文章过于理论缺少实际操作细节,这篇文章就多一些可操作性的内容吧. 注:这篇文章是以 MySQL 为背景,很多内容同时适用于其他关系型数据库,需要有一些索引知识为基础. 优化目标 ...

  3. mysql sql优化_浅谈mysql中sql优化

    说到sql优化,一般有几个步骤呢,在网上看到了一篇很不错的帖子.在这分享一下吧,也是自己学习的一个过程. 一.查找慢查询 1.1.查看SQL执行频率 SHOW STATUS LIKE 'Com_%'; ...

  4. 18.Mysql SQL优化

    18.SQL优化 18.1 优化SQL语句的一般步骤 18.1.1 通过show status命令了解各种SQL的执行频率 show [session|global] status; -- 查看服务器 ...

  5. mysql sql优化与调优机制详解_MySQL之SQL优化详解(一)

    目录 序言: 在我面试很多人的过程中,很多人谈到SQL优化都头头是道,建索引,explain分析,like全模糊会导致索引失效 云云,于是我问道:优化之前,需要找出数据库中比如超过2s的慢SQL,你是 ...

  6. mysql sql优化_MySQL优化SQL语句的步骤

    我们在执行一条SQL语句的时候,如果我们想要知道这条SQL语句查询了哪些表,有没有使用索引,获取数据的时候遍历了多少行数据,我们可以通过EXPLAIN命令来查看这些执行信息,这些执行信息统称为执行计划 ...

  7. mysql sql优化_Mysql的SQL优化指北

    要知道怎么优化首先要知道一条SQL是怎么被执行的 首先我们会连接到这个数据库上,这时候接待你的就是连接器.连接器负责跟客户端建立连接.获取权限.维持和管理连接. MySQL拿到一个查询请求后,会先到查 ...

  8. mysql sql 优化 博客园_Mysql的SQL优化指北

    概述 在一次和技术大佬的聊天中被问到,平时我是怎么做Mysql的优化的?在这个问题上我只回答出了几点,感觉回答的不够完美,所以我打算整理一次SQL的优化问题. 要知道怎么优化首先要知道一条SQL是怎么 ...

  9. 谈谈mysql优化_浅谈MySQL SQL优化

    本文首发于个人微信公众号<andyqian>,期待你的关注 前言 有好几天没有写文章了,实在不好意思.之前就有朋友希望我写写MySQL优化的文章.我迟迟没有动笔,主要是因为,SQL优化这个 ...

最新文章

  1. BZOJ3572: [Hnoi2014]世界树
  2. 《2020城市大脑全球标准研究报告》全文正式开放申领
  3. SAP CRM和C4C message category配置
  4. 在 Ubuntu 上安装 .NET SDK 或 .NET 运行时
  5. kali linux 桌面消失_kalilinux系统设置不见了的解决方案
  6. BugkuCTF-MISC题telnet
  7. Asp.net自定义控件开发任我行(1)-笑傲江湖
  8. 服务器系统计划任务不执行,Windows 2008 r2任务计划程序执行批处理失败问题解决方法...
  9. 【Java】异步回调转为同步返回
  10. QT实现串口调试助手(三):保存日志、QSS样式载入
  11. 关于使用硬盘对拷机后两硬盘UUID一样无法挂载问题
  12. 如何将交叉引用参考文献批量变为上标
  13. C#按汉字拼音首字母排序
  14. 从小样本学习出发,奔向星辰大海
  15. 全国计算机图书销售订单记录,销售订单管理信息系统.doc
  16. linux swift开发环境,Linux平台swift语言开发学习环境搭建
  17. 前端开发工程师如何在2013年里提升自己【转】--2016已更新升级很多何去何从?...
  18. [附源码]计算机毕业设计JAVA大学城二手书交易网站
  19. 嵩天python测验4_嵩天Python学习笔记-04
  20. Docker之漫漫人生路

热门文章

  1. pecs_泛型的PECS原则
  2. PopupMenu源码分析
  3. Dubbo SpringBoot 实战
  4. 论山寨手机与Android 【9】SmartPhone的硬件结构
  5. JAVA_EE(二)_WEB服务器开发
  6. ActionBar的简单使用
  7. 如何注册code.org网站账号
  8. 网络书签外链发布的注意方法
  9. 使用BurnAware免费版轻松刻录光盘
  10. 手机平板真假难辨,从xiaoxye p7谈起,鲁大师,安兔兔全部失败!