关于mysql:第45期一条-SQL-语句优化的基本思路

4次阅读

共计 2089 个字符,预计需要花费 6 分钟才能阅读完成。

SQL 语句优化是一个既相熟又生疏的话题。面对千奇百怪的 SQL 语句,尽管数据库自身对 SQL 语句的优化始终在继续改良、晋升,然而咱们不能齐全依赖数据库,应该在给到数据库之前就替它做好各种筹备工作,这样能力让数据库来有精力做它本人善于的事件。

就拿 MySQL 来讲,一条 SQL 语句从客户端收回到数据库端返回后果个别会经验几个阶段:词法解析、语法解析、语义解析、逻辑优化、物理优化、最终执行并返回后果。那么这几个阶段,咱们 DBA 能参加的也就是两个阶段:逻辑优化以及少许物理优化。所以在咱们 DBA 这侧,对 SQL 语句的优化简略来讲就是让咱们本人写的 SQL 语句能更好的适应数据库内置的优化规定,进一步让 SQL 语句在每个解决阶段能扫描更少的记录数量、字段数量来改善查问成果。

逻辑优化能够了解为基于 N 多数据库内置规定的预处理,规定定义越全面,对 SQL 语句优化的就越极致。比方应用表关联代替子查问、分组聚合条件上推、在特定条件下用内连贯来替换外连贯、视图上推到基表等等一系列优化措施。

物理优化能够了解为数据库依照以后 SQL 语句波及到的表统计信息、列统计信息、索引个数、索引优劣、以后运行负载、以后硬件资源等可变因素来决定如何生成最优执行门路的办法。

一般来讲,咱们拿到一条“不是很优化”、“烂的”、“慢的”等 SQL 语句(至于怎么拿到这条语句,不在本篇探讨范畴),应该依照以下几个步骤来逐渐剖析:
一、定位该 SQL 语句波及到的表构造,确认是磁盘表还是视图,如果是磁盘表,那么该思考以下几点:
  1. 这些表是否对立为 InnoDB 引擎(MySQL 5.7 以及以前一些老旧版本可能会有非 InnoDB 引擎表),如果不是,转换表引擎为 InnoDB。因为 MySQL 从 5.5 版本开始,所有针对存储层的优化都是针对 InnoDB 引擎的。
  2. 极个别表为长期表。查看长期表相干参数是否设置正当;或者说是否把长期表替换为磁盘表。
  3. 查问每张表的字段类型,看有无不合理的局部。
  4. 查问每张表的记录数,查看是否过大须要后续拆分。
  5. 查问每张表的统计信息,查看是否及时做了更新。
  6. 针对这些表构造做进一步剖析,查看索引设计是否正当?大抵会有以下几种后果:

(1). 都没有索引,有的连主键都没有。

(2). 都有主键或者惟一索引,然而没有二级索引。

(3). 有主键或者惟一索引,也有一些二级索引,并且二级索引可选择性也比拟优化。

(4). 有主键或者惟一索引,也有一些二级索引,然而这些二级索引可选择性很差。

二、如果有些表是视图,须要思考以下几点:
  1. 该视图外部的算法有两种,一种是长期表(TEMPTABLE)、另外一种是合并(MERGE)。能够针对这两种算法来别离测试视图整体性能哪个较优化。
  2. 该视图外部如果有很简单的解决逻辑,想方法把这部分内容简化或者从数据库剥离转交给利用解决,防止数据库将其劣势放大。
  3. 该视图如果非必须,可拆解为基表与下层 SQL 语句做合并解决,这样效率较之前更优化(比方视图外部多表关联与下层基表再次关联,拆分后,优化器就会有更多更优的表关联程序)。
三、到了这一步,如果是多张表关联,此处检查表关联键:
  1. 表关联键为主键和外键,也即两表用来关联的字段在一张表惟一并且在另一张表被援用,这时须要补充额定的过滤条件来缩小扫描记录数。
  2. 表关联键为非主键,也即两表用来关联的字段都不惟一,须要优化为惟一键值关联。
  3. 表关联键字段编码不统一,须要人为转换字段编码并改为统一。
四、基于以上几点,表构造剖析这块曾经大抵结束。接下来从 SQL 语句层面来剖析,比方这条 SQL 语句是否批改为更加优化的形式。能够思考以下两点:
  1. SQL 语句自身很简略,没有必要做批改。

    比方这条语句自身是 20 张表的内联查问,那它不够优化并不是因为写的不好,而是表关联个数切实太多。

  2. SQL 语句自身很简单,仔细分析后,能够简化这条语句的写法。

    简单 SQL 语句又能够分为很多类别,比方多张子表关联、多张表嵌套子查问、多个子查问合并输入、多个聚合类操作等等。每种都有不同的优化办法,后续我会一一介绍。

五、那么后面几点做完后,进一步剖析优化后 SQL 语句的执行打算(如果有条件模仿生产环境压力模型),个别思考如下几点:
  1. 改写后的语句执行打算很优化,走最合适的索引、语句自身也改的很简洁,那么这条语句改写实现。
  2. 改写后的语句执行打算没有走适合的索引,能够思考在表上建设适合的索引。如果建新索引后,这条语句执行成果很好,那么改写实现。
  3. 改写后的语句走了适合的索引,执行成果仍然不现实,这时可能有以下几种起因:

(1). 这条语句走的索引在不同过滤条件下,运行成果忽好忽坏。

比方日期字段,过滤条件为昨天的查问记录数为 100 条,过滤条件为前天的查问记录数则变为 1W 条。

(2). 这条语句走的索引较优,然而表记录数切实太大,走索引过滤的记录数也很多,须要从表构造这层做些优化。比方后面几期讲过的分区表、拆分表等办法;或者是从业务层面限度这条语句来扫描更少的记录数等等。

通过以上几个步骤,个别的语句基本上都能达到比拟优化的后果。后续我将逐渐介绍各种优化办法以及在 MySQL 里如何付诸于实际。


对于 MySQL 的技术内容,你们还有什么想晓得的吗?连忙留言通知小编吧!

正文完
 0