暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

MySQL查询优化

MySQL解决方案工程师 2019-09-02
1274

上周在MySQL团队的网络研讨会上,分享了MySQL查询优化相关内容,现在把内容整理一下,供各位参考。

内容分为如下几个方面:

  1. 基于成本的MySQL查询优化。

  2. 监视、分析和查询优化的工具有哪些?

  3. 数据访问方法与如何选择索引。

  4. 如何对连接进行优化。

  5. 如何影响优化器。

接下来,简明介绍一下相关内容,网络研讨会的视频附在后面。

基于成本的MySQL查询优化:


MySQL的优化器将SQL查询作为输入,并产生一个计划来执行该查询。
例如,应该按什么顺序连接表以及应该使用哪些索引。目标是能够从众多可能的执行计划中找到最佳的执行计划。
MySQL使用基于成本的优化器。计划的成本大致反映了查询所需的资源,其中主要因素是计算查询时将要访问的行数。在优化过程中,优化器会选择连接顺序,决定使用哪个索引等等。同时,优化器还会根据从存储引擎获取的数据的统计信息作出决定。并且还依赖于数据字典中的元数据信息。


因此,查询优化的总体思路如上图所示。

基于成本的查询优化器将为不同的操作分配成本,如表扫描和索引查找。
成本单位是从磁盘读取随机数据页的成本。所有其他成本数字都与此成本单位有关。基于这些成本,优化器将计算可供选择的计划的成本。最终它将选择成本最低的计划。


这是MySQL中成本模型的一个非常简单的视图。
作为输入,它需要基本操作,例如从表格读取数据或连接两个表格。作为输出,它产生对执行此操作的成本的估计。除了成本估算之外,它还会估算该操作产生的行数。成本模型由计算不同操作的成本和估计行数的公式组成。除了成本公式之外,成本模型还包含一组“成本常数”。这些是MySQL服务器在执行查询时执行的基本操作的成本。
成本模型使用来自数据字典的信息和来自存储引擎的统计信息来进行计算。主要的统计信息是表中的行数,对于索引,也获得基数,即有多少个不同的列值,以及索引范围中的行数。从数据字典中,我们使用关于行和索引的信息:如行和键的长度,唯一性以及列是否可以为空。
在MySQL 5.7中,已经配置了成本模型。成本常数存储在数据库表中,可以更改以更好地表示系统的特征。
使用这个模型,优化器在大多数情况下会选择一个最好的计划。但是,有时候优化器不能成功找到最佳计划。这可能是由于其决策所依据的数据不准确或由于成本模型本身的不准确性。


监视分析工具

了解MySQL的优化器原理之后,我们来通过一些工具来对MySQL的性能进行监视分析。工具包括如下:


MySQL企业版监控器的查询分析器提供了一个概览,使用户能够快速识别开销大的查询。用户还可以对单个查询进行深入研究,以查看关于查询的细粒度统计信息。

Performance Schema有大量的表与性能相关的数据。

events_statements_history表提供最近执行的查询的统计信息。

events_statements_summary_by_digest表中汇总类似查询的数据。

file_summary_by_event_name表包含获取文件I/ O的统计信息。

table_io_waits_summary表提供有关表和索引使用情况的统计信息。


语句事件表提供有关最近运行的查询的信息。
events_statements_current表将显示每个连接或线程的当前语句。
历史表默认给出每个线程最近的10条语句,
history_long表给出了全部10000条最新的语句。
历史记录表的大小是可配置的。
已经用红色标出了这些表格中的最有用的信息。
例如,TIMER_WAIT给出了执行查询需要多长时间。单位是皮秒。
ROWS_SENT是结果中的行数,而ROWS_EXAMINED是执行查询时必须访问的行数。
ROWS_EXAMINED比ROWS_SENT大得多,通常表明查询需要优化。
CREATED_TMP_DISK_TABLES告诉查询是否创建了磁盘上的临时表。


语句摘要是将类似查询分组在一起的一种方法。

在这里你可以看到两个查询的例子,这两个查询的区别,仅在于使用的常量。这样的查询将得到相同的摘要。摘要计算也会忽略空白和数值。

events_statements_summary_by_digest表包含每个摘要汇总的统计信息。

DIGEST_TEXT提供规范化的查询文本,COUNT_STAR是执行此类型查询的次数。

SUM_TIMER_WAIT是执行此查询所用的总时间,AVG_TIMER_WAIT是每次执行的平均时间。大多数其他列是各个查询的值的总和。

在调查最近的性能退化时,FIRST_SEEN列对于查找可能导致问题的新查询非常有用。


Performance schema非常庞大,有很多细节。因此,MySQL团队开发了sys_schema,这是一个视图,存储过程和函数的集合,旨在使访问Performanceschema数据变得更加容易。




EXPLAIN有三种格式,表格,JSON及可视化。通过使用EXPLAIN可以获取查询的执行计划。
结构化的EXPLAIN以JSON格式提供查询计划,可以通过在EXPLAIN之后指定FORMAT= JSON来获得此信息。使用JSON可以更容易地显示查询的结构。

MySQL Workbench使用结构化EXPLAIN的输出来优化查询计划。

上图按从左到右的连接顺序显示表。红色框表示全表扫描,而绿色框表示使用索引查找。对于每个表,显示使用的索引。还要注意的是,每个表格的框上方是每个表访问所发现的行数的估计值以及访问该表的成本。


如果您想更深入地了解为什么选择某个查询计划,那么优化器跟踪非常有用。虽然EXPLAIN显示选定的计划,但优化程序跟踪显示为什么选择计划:

您将能够看到替代计划,估计成本以及做出的决策。跟踪采用JSON格式。

要打开optimizer_trace,可以在optimizer_trace会话变量中设置enabled标志。解释或运行查询后,可以从informationschema中的optimizer_trace表中获取跟踪。通常会将跟踪转存到文件以供进一步检查。

optimizer_trace表有3个其他列,查询的文本,

Missing_bytes_beyond_max_mem_size。如果这不是零,则需要增加用于捕获跟踪的内存缓冲区的大小。

insufficient_privileges。如果不为零,则表示用户缺乏查看有关查询或查询中使用的存储例程的信息的权限。


数据访问方法

选择访问方法的目标是为查询中的每个表找到读取所需数据的最佳方式。

对于查询的每个表,我们执行以下操作:

检查访问方法是否有用,估计使用该访问方法的成本,以及选择成本最低的访问方法。

关于访问方法的详细内容请参看视频。


连接的优化

连接优化器的作用是找到连接表的最佳顺序。

我们的连接优化器使用“贪婪搜索策略”来计算所有可能的连接顺序。

这是以深度优先的方式完成的。为了缩小范围,将会删去比迄今为止发现的最佳计划花费更多的部分计划。为了使这种删去更高效,首先会对大小和键依赖关系进行排序。这样增加了尽早找到一个好计划的机会,以便更多的计划将被删去。连接优化器默认也会删去一些不那么有希望的计划,而这些计划不一定比目前的最佳计划花费更多。在某些情况下,可能会因此而错过最佳计划。探索式删去可以通过将optimizer_prune_level设置为0来关闭。


1.我现在将展示一个关于连接优化器如何工作的例子。

我们的示例查询加入了三个表格,语言,国家和城市。

优化器通常会从最小的表开始。语言是最小的表

2.它首先添加国家

3.然后城市。此连接顺序的估计总成本为26568

4.将其记录为迄今最好的计划

5.然后它回溯并添加城市

6.然后是国家。此连接顺序的总成本为32568,比之前的计划成本大。现在所有以语言开始的可能计划都已经尝试过了,我们将继续以国家为起点的计划。

7.我们首先添加语言

8.然后城市。总成本是627

9.所以这个连接顺序是迄今为止最好的。

10然后我们尝试将城市作为第二张表,并且看到这个部分计划的成本是1245。

11.这比迄今为止发现的最佳计划还要大。因此,我们将在此停止并且不向此部分连接顺序添加更多表。

12.我们继续与城市和单独访问该表的成本是862。

13.这也比迄今为止的最低成本要高,我们将删去这个搜索树的其余部分。

通过这种方式,连接优化器已经确定最佳连接顺序是Country优先,然后是Language,然后是City。



可以通过改变连接的顺序进行优化,翻转连接顺序,执行时间从15秒减少到不到1秒。反向顺序更好的原因是,实际上很少有客户的帐户余额很低。

因此,通过从客户表开始,大多数行将被过滤掉,并且实际上很少有查询到订单表。


影响优化器

可以通过上图的方法对优化器进行影响,以达到预期效果。


MySQL 5.7引入了优化器提示的新语法。

在SELECT之后,新的提示应该放在一个特殊的注释中

这些提示中的许多提示都对应于optimizer_switch会话变量可以控制的功能。这些提示允许打开或关闭单个查询的功能,或者仅用于查询的某些表或索引。


MySQL 8.0,已经添加了提示来控制派生表和视图是否合并。

还添加了几个连接顺序提示。这些新的联接提示比现有的STRAIGHT_JOIN提示更灵活,它要求FROM子句中的表按特定顺序列出。


MySQL8.0 还可以在查询期间临时设置会话变量。


从MySQL5.7开始,提供了一个插件,可用于在不更改应用程序的情况下重写有问题的查询。

查询可以在到达MySQL服务器时重写。

用户可以使用这个插件添加提示,修改连接顺序等等。

在这张幻灯片的例子中,插入一条规则来将FORCEINDEX提示添加到匹配模式的查询中。与performance schema中使用的相同的查询摘要用于传入查询与重写规则的高效匹配。

这样,对于不符合任何重写规则的查询,应该几乎没有开销。


以上内容是关于MySQL查询优化的一个简明总结,详细内容请观看网络研讨会的视频。

感谢您关注MySQL!



mysql
最后修改时间:2019-12-24 14:17:20
文章转载自 MySQL解决方案工程师,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

PHP网站源码双龙网站改版南山网络营销盐田网页设计吉祥百姓网标王推广福田SEO按效果付费福永外贸网站设计吉祥至尊标王平湖百姓网标王光明外贸网站设计大浪网页制作观澜seo排名永湖网站建设设计坑梓网站改版光明网站制作南山网站搭建同乐百度网站优化排名坪地网络营销石岩SEO按天收费盐田外贸网站设计松岗网站推广方案坂田网站推广方案大浪网络营销丹竹头网站优化排名观澜网站建设设计坪山建设网站深圳网页制作民治网站关键词优化丹竹头网站定制坪地如何制作网站南联网站建设设计歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

PHP网站源码 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化