MySQL8.0 优化器介绍(四)

庖丁解牛|图解 MySQL 8.0 优化器查询转换篇 简介:本篇介绍子查询、分析表和JOIN的复杂转换过程 一 背景和架构 在《庖丁解牛-图解MySQL 8.0优化器查询解析篇》一文中我们重点介绍了MySQL最新版本8.0.25关于SQL基本元素表、列、函数、聚合、分组、排序等元素的解析、设置和转换过程,本篇我们继续来介绍更为复杂的子查询、分区表和JOIN的复杂转换过程,大纲如下: Transformation remove_redundant_subquery_clause :Permanently remove redundant parts .. 阅读详情
  • GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。
  • GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。
  • 作者: 奥特曼爱小怪兽
  • 文章来源:GreatSQL社区原创

往期回顾

MySQL8.0 优化器介绍(一)

MySQL8.0 优化器介绍(二)

MySQL8.0 优化器介绍(三)

MySQL8.0在优化器上做了很多努力和优化,仍然不足以保证每条sql,都能拥有合理的执行计划,有些情况需要通过hint来干预。MySQL8.0在hint的种类上进行了新增。本篇主要讲我们可以有哪些方法影响优化器。

优化器配置 Configuring the Optimizer

有很多方法影响优化器。

configuration options

mysql.engine_cost , mysql.server_cost 具体表字段的含义,怎么配置,配置后怎么生效的细节见官网。需要注意的是,配置完以上表后,得做一个FLUSH OPTIMIZER_COSTS; 的动作。

另外还有两个重要参数 optimizer_prune_level 、optimizer_search_depth 值得注意。

Optimizer Switches

optimizer switches 是一个复合的option 集。8.0.25 默认的optimizer switches

mysql> show  variables  like '%swi%' \G
*************************** 1. row ***************************
Variable_name: optimizer_switch
        Value: index_merge=on,index_merge_union=on,
               index_merge_sort_union=on,index_merge_intersection=on,
               engine_condition_pushdown=on,index_condition_pushdown=on,
               mrr=on,mrr_cost_based=on,block_nested_loop=on,
               batched_key_access=off,materialization=on,
               semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,
               subquery_materialization_cost_based=on,
               se_index_extensions=on,condition_fanout_filter=on,
               derived_merge=on,use_invisible_indexes=off,skip_scan=on,
               hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,
               hypergraph_optimizer=off,derived_condition_pushdown=on
1 row in set (0.00 sec)

optimizer switches 尽管可以会话级设置,但大多数情况下,我们都当作一个全局参数在用。

特别是5.7升级8.0,8.0小版本升级的时候,optimizer switches的检查必须作为一个单独项。前面的文章中已经介绍了10多种优化器的策略、算法。更多细节参考(https://dev.mysql.com/doc/refman/8.0/en/switchable-optimizations.html)

Optimizer Hints

(https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html)

Optimizer Hints的特性是5.7引入的,并在8.0做了扩展。可以通过hint 来影响查询计划的执行。

Hint 比optimizer switches的选项控制更精细,可以做到query block,table,index 三级。并且支持在查询期间更改配置选项的值,比会话级修改参数更细。比如可以限制一个sql的执行时间:

SELECT /*+ MAX_EXECUTION_TIME(2000) */
 id, Name, District
 FROM world.city
 WHERE CountryCode = 'AUS';
 ##查询被限制在2s之内。

Table 8.2 Optimizer Hints Available

图片

  • Global: The hint applies to the whole query.
  • Query Block: The hint applies to a group of joins. For example, the top level of the query is a query block; a subquery is another query block. Hints that apply to a query block can in some cases also take the table names for a join to limit the hint to a specific join.
  • Table: The hint applies to a specific table.
  • Index: The hint applies to the use of a specific index.

hint的语法 /*+ ... */ 注意三个点的前后都有一个空格。语法树都比较好看,举例几个比较难懂的语法。

#QB_NAME() 的用法。
可以把一个复杂的查询,划分成多个 query_block,然后再针对每个 qb进行hint的调优

#定义一个qb
SELECT /*+ QB_NAME(payment) */
 rental_id
 FROM sakila.payment
 WHERE staff_id = 1 AND customer_id = 75;

#复杂查询中,对一个qb进行hint
 SELECT /*+ NO_INDEX_MERGE(@payment payment) */
       rental_id, 
       rental_date,
       return_date
  FROM sakila.rental
 WHERE rental_id IN (
                     SELECT /*+ QB_NAME(payment) */
                            rental_id
                       FROM sakila.payment
                      WHERE staff_id = 1 AND customer_id = 75);

SELECT /*+ NO_INDEX_MERGE(payment@payment) */
       rental_id, 
       rental_date,
       return_date
  FROM sakila.rental
 WHERE rental_id IN (
                     SELECT /*+ QB_NAME(payment) */
                            rental_id
                       FROM sakila.payment
                      WHERE staff_id = 1 AND customer_id = 75);
#查询期间更改配置选项的值
SELECT /*+ SET_VAR(join_buffer_size = 1048576)
           SET_VAR(optimizer_search_depth = 0) */
       CountryCode, 
       country.Name AS Country,
       city.Name AS City, 
       city.District
  FROM world.country IGNORE INDEX (Primary)
 INNER JOIN world.city IGNORE INDEX (CountryCode)
         ON city.CountryCode = country.Code
      WHERE Continent = 'Asia';

 #SET_VAR一次只能修改一个vairable,多个vairable 需要多个SET_VAR
 #SET_VAR 不支持表达式,=号右边必须是具体的值

ps:怎么练习 sql 级别的hint的使用?

  1. 多读几遍25种hint的描述。
  2. 拿着一个正常的执行计划做参考,把一个异常的执行计划试着用hint改到期望的计划。
  3. 大多数的hint都是成对出现的,有关,有开两种组合。把一个正常的计划,试着用hint把计划改得糟糕。
  4. 从简单的sql,单表的入手。逐渐过渡到多表,单机,分布式数据库
  5. google MySQL hints 的经验 并实践。

Index Hints

这个大家应该很熟悉,ignore、use、force index

SELECT ci.CountryCode, 
       co.Name AS Country,
       ci.Name AS City, 
       ci.District
  FROM world.country co IGNORE INDEX (Primary)
 INNER JOIN world.city ci IGNORE INDEX (CountryCode)
    ON ci.CountryCode = co.Code
 WHERE co.Continent = 'Asia';

 SELECT *
   FROM world.city USE INDEX FOR ORDER BY (Primary)
  WHERE CountryCode = 'AUS'
  ORDER BY ID;

资源组(Resource Groups)

(https://dev.mysql.com/doc/refman/8.0/en/resource-groups.html#resource-group-restrictions)

对于high-concurrency systems的场景,MySQL8.0 在server 层,提供了一个resource groups 特性。

select  *  from  information_schema.RESOURCE_GROUPS \G
*************************** 1. row ***************************
   RESOURCE_GROUP_NAME: USR_default
   RESOURCE_GROUP_TYPE: USER
RESOURCE_GROUP_ENABLED: 1
              VCPU_IDS: 0x302D35
       THREAD_PRIORITY: 0
*************************** 2. row ***************************
   RESOURCE_GROUP_NAME: SYS_default
   RESOURCE_GROUP_TYPE: SYSTEM
RESOURCE_GROUP_ENABLED: 1
              VCPU_IDS: 0x302D35
       THREAD_PRIORITY: 0
2 rows in set (0.00 sec)

CREATE RESOURCE GROUP my_group  
TYPE = USER  
VCPU = 2-3,6,7 
THREAD_PRIORITY = 0 
ENABLE;

##RESOURCE_GROUP 是影响线程级别的,需要安装商业版本的thread_pool 
##(http://www.tdpub.cn/Blog/detail/id/1007.html)  thread_pool相关介绍 

##(https://zhuanlan.zhihu.com/p/114149600)  
##MySQL源码级线程init过程的分析 高并发创建MySQL线程时,遇到瓶颈,可能用得到。注意MySQL可以允许2000个并发同时运行与MySQL 1秒内创建200个并发 是不一样的概念。前者类似于高速上的车,后者类似于高速的入口。
##另外创建会话(连接)时的init 与show  processlist 看到State='init' 不一样。
##后面我的同事会投一篇<从processlist.state分析SQL执行阶段>的文章出来介绍。

##(https://zhuanlan.zhihu.com/p/114343815)   MySQL源码级连接与线程管理

 SELECT THREAD_ID, RESOURCE_GROUP  FROM performance_schema.threads  limit 5;
+-----------+----------------+
| THREAD_ID | RESOURCE_GROUP |
+-----------+----------------+
|         1 | SYS_default    |
|         3 | SYS_default    |
|         4 | SYS_default    |
|         5 | SYS_default    |
|         6 | SYS_default    |
+-----------+----------------+

资源组可用于指定线程允许使用哪些CPU,以及线程应使用哪个优先级执行。
这对于确定某些线程的优先级非常有用
执行优先级高于其他线程或防止资源争用。

本系列文章一共4篇,概括地介绍了优化器是怎么工作的,join的优化算法,以及优化 join的方法;以及怎么配置optimizer。

MySQL使用基于成本的优化器,其中估计查询执行的每个部分的成本,并选择总体查询计划以最小化成本。作为优化的一部分,优化器将使用各种转换重写查询,找到最佳连接顺序,并做出其他决定,例如应使用哪些索引。

MySQL 已经有三种基本的join 算法: NL,BNL,HASH JOIN 。HASH JOIN 弥补了NL 在缺少索引,或者索引选择性不佳时,触发的性能问题。同时HASH JOIN 也带来自身的一些性能问题。

重点聚焦了三种join 优化,index_merge 可以使用多个索引来提高效率。MRR 是通过减少随机IO 来提高效率。BKA=BNL+MRR

另外还介绍了多种影响优化器的方法。

一些有意思的链接:

(http://www.unofficialmysqlguide.com/index.html)(https://www.percona.com/blog/count-vs-countcol-in-mysql/)

Enjoy GreatSQL :)

关于 GreatSQL

GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。

相关链接: GreatSQL社区 Gitee GitHub Bilibili

GreatSQL社区:

image

社区有奖建议反馈: https://greatsql.cn/thread-54-1-1.html

社区博客有奖征稿详情: https://greatsql.cn/thread-100-1-1.html

社区2022年度勋章获奖名单: https://greatsql.cn/thread-184-1-1.html

(对文章有疑问或者有独到见解都可以去社区官网提出或分享哦~)

技术交流:

image-20221030163217640

MySQL 8.0 Server层最新架构详解 简介:本文基于MySQL 8.0.25源码进行分析和总结。这里MySQL Server层指的是MySQL的优化器、执行器部分。我们对MySQL的理解还建立在5.6和5.7版本的理解之上,更多的是对比PostgreSQL或者传统数据库。然而从MySQL 8.0开始,持续每三个月的迭代和重构工作,使得MySQL Server层的整体架构有了质的飞越。下面来看下MySQL最新的架构。 作者 | 道客 来源 | 阿里技术公众号 一 背景和架构 本文基于MySQL 8.0.25源码进行分析和总结。这里My. 阅读详情

相关推荐

庖丁解牛-图解MySQL 8.0优化器查询转换篇

简介:在《庖丁解牛-图解MySQL 8.0优化器查询解析篇》一文中我们重点介绍了MySQL最新版本8.0.25关于SQL基本元素表、列、函数、聚合、分组、排序等元素的解析、设置和转换过程,本篇我们继续来介绍更为复杂的子查询、分区表和JOIN的复杂转换过程。 作者 | 道客 来源 | 阿里技术公众号 一 背景和架构 在《庖丁解牛-图解MySQL 8.0优化器查询解析篇》一文中我们重点介绍了MySQL最新版本8.0.25关于SQL基本元素表、列、函数、聚合、分组、排序等元素的解析、设置和转换过程,本.

阿里云云栖号 1367

使用优化器提示(Optimizer Hints)

优化器提示(Optimizer Hints)可以用在SQL语句中改变执行计划。

通往OCM之路 3339

MySQL 8.x新特性之——优化器索引

MySQL 8.x中新增了三种索引方式,如下所示。 隐藏索引 降序索引 函数索引 一、隐藏索引 1.隐藏索引概述 MySQL 8.0开始支持隐藏索引(invisible index),不可见索引。 隐藏索引不会被优化器使用,但仍然需要进行维护。 应用场景:软删除、灰度发布。 在之前MySQL的版本中,只能通过显式的方式删除索引,如果删除后发现索引删错了,又只能通过创建索引的方式将删除...

冰河的专栏 2340

图文解读MySQL/GreatSQL体系架构

*GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。往期系列回顾图文结合系列之带你搞懂MySQL日志系列很多小伙伴使用了GreatSQL,但是对GreatSQL的底层原理还不是很了解,今天就带大家一起揭开GreatSQL体系架构的神秘面纱!首先来回顾一张经典的体系架构图:图1_GreatSQL5.7 版本体系架构图由此可以发现,GreatSQL5.7 由以下几部分组成连...

老叶茶馆 520

别再死记公式了!用HFSS/CST手把手教你仿真一个2.4GHz WiFi的PIFA天线(附参数调试技巧)

本文详细介绍了使用HFSS和CST仿真软件设计2.4GHz WiFi PIFA天线的全流程,包括建模准备、分步操作指南和参数调试技巧。通过可视化结果和实战案例,帮助工程师快速掌握天线设计的关键参数优化方法,提升辐射性能和工作效率。

weixin_31682031的博客 335

双目视觉入门实战:用Matlab标定相机,再到Python OpenCV完成测距的完整链路

本文详细介绍了双目视觉技术的完整实现流程,从Matlab相机标定到Python OpenCV测距的全链路实践。重点解析了Matlab与OpenCV的参数转换技巧,以及立体校正、视差计算等关键步骤的代码实现,帮助开发者快速掌握双目测距系统的搭建方法。

weixin_29166013的博客 445

MySQL 5.7-8.9.3 Optimizer Hints(优化器提示)

One means of control over optimizer strategies is to set theoptimizer_switchsystem variable (seeSection8.9.2, “Switchable Optimizations”). Changes to this variable affect execution of all subsequent queries; to affect one query differently from another...

tangwenqiang177的专栏 1216

数学分析五领域全景:实分析、复分析、泛函分析、傅里叶分析、凸分析

五种分析,五种视角,同一个目标。理解一个系统,首先要找到它的不变量。

li880862的博客 192

SQL高级优化--优化器提示

本文结合实际案例讲述MySQL的Comment Syntax(注释语法)中Optimizer Hints(优化器提示)的作用和用法,以及如何通过有话题时期对SQL进行优化。绝对的干货文章哦!

我的博客 1510

3D模型文件格式全解析:从STL到glTF,10种主流格式与转换实战指南

在三维数字内容创作与工程制造领域,3D模型文件格式是数据交换与协作的基石。其核心原理在于以不同的数据结构(如三角网格、NURBS曲面、边界表示等)对三维物体的几何、外观及场景信息进行编码。理解这些格式的技术特性,对于保障数据完整性、提升工作流效率具有关键价值,广泛应用于3D打印、游戏开发、影视动画及工业设计等场景。例如,面向增材制造的STL格式以其极简的三角面片结构成为行业通用语,而支持丰富材质与动画的FBX格式则在影视游戏管线中扮演核心角色。本文聚焦于STL、OBJ、FBX、3MF、STEP等10种主流格

weixin_28520495的博客 356

USVInland 数据集实战:4个月采集27段数据,26公里内河SLAM评测

本文详细解析了USVInland数据集在内河SLAM算法评测中的应用实践。通过4个月采集的27段共26公里真实多传感器数据,该数据集有效解决了GPS信号遮挡、动态反射干扰等内河无人船SLAM核心挑战。文章从数据预处理、算法优化到性能评测,全面展示了如何利用毫米波雷达与视觉数据的时空对齐特性提升定位精度,为水上无人驾驶技术提供重要基准。

weixin_33158887的博客 341

Changes in GreatSQL 8.0.25-16(2022-5-16)

GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。 [toc] 1.新增特性 1.1 新增仲裁节点(投票节点)角色 该节点仅参与MGR投票仲裁,不存放实际数据,也无需执行DML操作,因此可以用一般配置级别的服务器,在保证MGR可靠性的同时还能降低服务器成本。 新增参数group_replication_arbitrator用于设置仲裁节点。 若想新增一个仲裁节点,只需在 my.cnf 配置文件中添加如下配置: group_replication_arbitrator = tru.

GreatSQL2021的博客 363

手把手教你离线部署bert-base-uncased模型(附完整文件清单)

本文提供了一份详尽的bert-base-uncased模型离线部署指南。针对严格内网或无网络环境,文章不仅列出了包括config.json、pytorch_model.bin在内的完整必需文件清单,还详细解释了每个文件的作用,并给出了使用snapshot_download工具或手动下载的两种文件获取方法。重点阐述了如何正确设置本地路径、编写健壮的加载代码,并通过多层次验证确保模型在离线环境下成功运行,有效解决了部署过程中常见的文件缺失和路径错误问题。

weixin_29034963的博客 320

【MySQL】深入理解MySQL索引优化器原理(MySQL专栏启动)

本文将解读MySQL数据库查询优化器(CBO)的工作原理。简单介绍了MySQL Server的组成,MySQL优化器选择索引额原理以及SQL成本分析,最后通过 select 查询总结整个查询过程。

小明的Java问道之路 9087

《RT-DETR魔术师》专栏介绍 & 优快云独家改进创新实战 & 专栏目录

通过本专栏的阅读,后续你也可以自己魔改网络,在网络不同位置(Backbone、head、neck、loss等)进行魔改,实现创新!!!

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 7367

阿里九宫格验证码 (Baxia SecCaptcha) 逆向工程与自动化求解

实现对阿里巴夏 (Baxia) 九宫格点击验证码的全自动求解模式说明依赖浏览器模式通过 Puppeteer/Playwright 控制真实浏览器,享有完整 DOM/Canvas/WASM 环境需要 Chrome/Chromium纯算模式脱离浏览器,通过 HTTP API + Node.js WASM 解密完成求解无需浏览器。

猫敷雪 379

MySQL8.0 优化器介绍(一)

前言线上,遇到一些sql性能问题,需要手术刀级别的调优。optimizer_trace是一个极好的工具,已经有很多资料介绍optimizer_trace怎么使用与阅读。有必要再介绍一下我们平时不太能注意到,但是又对sql性能起着绝对作用的优化器。优化器是啥?在sql整个生命周期里处于什么样的位置,起到什么样的作用,cmu15445 课程(https://15445.courses.cs.cmu.e...

老叶茶馆 973

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

MySQL8.0 · 优化器新特性 · Cost Model, 直方图及优化器开销优化

MySQL当前已经发布到MySQL8.0版本,在新的版本中,可以看到MySQL之前被人诟病的优化器部分做了很多的改动,由于笔者之前的工作环境是5.6,最近切换到最新的8.0版本,本文涵盖了一些本人感兴趣的和优化器相关的部分,主要包括MySQL5.7的cost model以及MySQL8.0的直方图功能。 本文基于当前最新的MySQL8.0.12版本,主要是讲下cost model 和 histo...

阿里云云栖号 1117

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

庖丁解牛-图解MySQL 8.0优化器查询解析篇

简介:SQL优化器本质上是一种高度抽象化的数据接口的实现,经过该设计,客户可以使用更通用且易于理解的SQL语言,对数据进行操作和处理,而不需要关注和抽象自己的数据接口,极大地解放了客户的应用程序。 作者 | 道客 来源 | 阿里技术公众号 一 背景和架构 我们都知道,利用编写程序来动态实现我们应用所需要的逻辑,从而程序执行时得到我们需要的结果。那么数据库就是一种通过输入SQL字符串来快速获取数据的应用。当然,假设没有数据库这种系统应用,用程序如何实现呢?我们可能会发现,即使不管数据如何存储、数据.

阿里云云栖号 1373

MySQL8.0 优化器介绍(二)

*GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。上一篇 MySQL8.0 优化器介绍(一)介绍了成本优化模型的三要素:表关联顺序,与每张表返回的行数(过滤效率),查询成本。而join算法又是影响表关联效率的首要因素。join算法(Join Algorithms)join在MySQL 是一个如此重要的章节,毫不夸张的说,everything is a join。截止到...

老叶茶馆 254

MySQL8.0 优化器介绍(三)

*GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。往期回顾MySQL8.0 优化器介绍(二)MySQL8.0 优化器介绍(一)本篇将进一步深入介绍优化器相关的join优化为更好的理解本篇内容需要提前看一下以下内容:单表访问的方法,参考《MySQL 是怎样运行的:从根儿上理解 MySQL》第10章"单表访问方法"更多select语句级别的优化细节 见(https://d...

老叶茶馆 351

mysql 8介绍,MySQL 8.0 简介

MySQL 5.7 到 8.0,Oracle 官方跳跃了 Major Version 版本号,随之而来的就是在 MySQL 8.0 上做了许多重大更新,在往企业级数据库的路上大步前行,全新 Data Dictionary 设计,支持 Atomic DDL,全新的版本升级策略,安全和账号管理加强,InnoDB 功能增强等,目前小版本已经 release 到 8.0.16,新的功能仍然在持续推出。My...

weixin_30106425的博客 1万+

庖丁解牛 - 图解MySQL 8.0优化器查询解析篇

一 背景和架构 我们都知道,利用编写程序来动态实现我们应用所需要的逻辑,从而程序执行时得到我们需要的结果。那么数据库就是一种通过输入SQL字符串来快速获取数据的应用。当然,假设没有数据库这种系统应用,用程序如何实现呢?我们可能会发现,即使不管数据如何存储、数据是否并发访问,仍然需要不断通过修改程序处理不同应用对数据的不同请求。比如大数据领域,我们通常通过非关系型数据库的API,实现对数据的获取。然而这种方式虽然入门简单,但是维护极难,而且通用性不强,即使不断进行软件架构设计或者抽象重构,仍然需要不断地..

数据库技术 471
上一篇: MySQL 8.0不再担心被垃圾SQL搞爆内存
下一篇: MySQL触发器Trigger加载以及目前局限
GreatSQL社区
博客等级 码龄5年 1210粉丝 390原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值