加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

SQL业务审查与优化

发布时间:2022-04-03 11:45:54 所属栏目:MySql教程 来源:互联网
导读:审核 什么是业务审核 类似与code review 评审业务Schema和SQL设计 偏重关注性能 是业务优化的主要入口之一 审核提前发现问题,进行优化 上线后通过监控或巡检发现问题,进行优化 Schema设计审核 表和字段命名是否合规 字段类型,长度设计是否适当 表关联关
       审核
 
       什么是业务审核
       类似与code review
       评审业务Schema和SQL设计
       偏重关注性能
       是业务优化的主要入口之一
       审核提前发现问题,进行优化
       上线后通过监控或巡检发现问题,进行优化
 
Schema设计审核
表和字段命名是否合规
字段类型,长度设计是否适当
表关联关系是否合理
主键,更新时间保留字段等是否符合要求
约束,默认值等配置是否恰当
了解业务,表数据量,增长模式
数据访问模式,均衡度
根据业务需求,表是否需要分区,是否有数据什么周期
 
SQL语句审核
SQL语句的执行频率
表上是否有合适的索引
单次执行的成本
执行模式,锁情况分析
关注事务上下文
 
什么时候需要审核
业务开发阶段,上线前
业务版本变更,线上更新前
新表和SQL上线
SQL查询条件变化
SQL查询频率变化
业务逻辑导致现有表数据量规模变化
 
业务发布流程
SQL审核需要开发与应用运维支持
充分沟通,做好必要性说明和教育工作
指定业务发布流程,嵌入DBA审核环节
积累经验,不断完善评审方法
  
mysql是否在扫描额外的记录
在确定查询只返回需要的数据后,接下来应该看看查询为了返回结果是否扫描了过多的数据。
 
mysql查询开销的三个指标:
响应时间
扫描的行数
返回的行数
 
查询执行的基础
 
mysql查询执行路径
 SQL业务审核与优化
SQL业务审核与优化
 
客服端发送一条查询给服务器
服务器先检查缓存。如果命中缓存,则立刻返回结果。否则进入下一阶段。
服务器端进行SQL解析,预处理,再由优化器生成对应的执行计划。
mysql根据优化器生成的执行计划,调用存储引擎的API来执行查询。
将结果返回给客户端
 
查询优化器
 
一条查询可以有很多种执行方式,最后都返回相同的结果。
优化器的作用就是找到这其中最好的执行计划。
 
mysql使用基于成本的优化器,它将尝试预测一个查询使用某种执行计划时的成本,并选择其中成本最小的一个。
 
通过查询当前会话的last_query_cost的值来得知Mysql计算的当前查询的成本。
mysql>selectcount(*) from film_actor; +----------+|count(*) |+----------+|5462|+----------+1 row inset (0.00 sec)
 mysql> show status like 'last_query_cost'; +-----------------+-------------+ | Variable_name | Value | +-----------------+-------------+ | Last_query_cost | 1040.599000 | +-----------------+-------------+
这个结果表示mysql优化器认为大概需要做1040个数据页的随机查找才能完成上面的查询。这是根据一系列的统计信息计算得来的:每个表或者索引的页面个数,索引的基数(索引中不同值的数量),索引和数据行的长度,索引分布情况。
 
优化策略:
静态优化
直接对解析树进行分析,并完成优化。优化器通过一些简单的代数变换将where条件转换成另一种等价形式。静态优化在第一次完成后一直有效。可以认为这是一种"编译时优化"
动态优化
动态优化和查询的上下文有关。也和其他很多因素有关,例如where中的取值,索引中条目,等等。每次查询的时候都重新评估,可以认为这是一种"运行时优化"
 
在查询中添加hint,提示优化器,
 
优化器的局限性
 
1 关联子查询
mysql的子查询实现得非常糟糕;最糟糕的一类查询是where条件中包含IN()的子查询语句。
例如,我们希望找到sakila数据库中,演员actor_id为1,参演过的所有影片信息。很自然的,我们会按照下面的方式
 
当然我们可以使用连接替代子查询重写这个SQL,来优化;
 
mysql> explain select*from film f innerjoin film_actor fa where f.film_id=fa.film_id and actor_id =1; +----+-------------+-------+--------+------------------------+---------+---------+-------------------+------+-------+| id | select_type |table| type | possible_keys |key| key_len | ref | rows | Extra |+----+-------------+-------+--------+------------------------+---------+---------+-------------------+------+-------+|1| SIMPLE | fa | ref |PRIMARY,idx_fk_film_id |PRIMARY|2| const |19|||1| SIMPLE | f | eq_ref |PRIMARY|PRIMARY|2| sakila.fa.film_id |1||+----+-------------+-------+--------+------------------------+---------+---------+-------------------+------+-------+2 rows inset (0.00 sec)
如何用好关联子查询,很多时候,关联子查询也是一种非常合理,自然,甚至是性能最好的写法。
where in()肯定是不行的,但是 where exists()有时是可以的;
 
2 union的限制
 
有时,mysql无法将限制条件从外层"下推"到内层,这使得原本能够限制部分返回结果的条件无法应用到内层查询的优化上。
 
如果希望union的各个子句能够根据limit只取部分结果集,或者希望能够先拍下再合并结果集的话,就需要在union的各个子句中分别使用这些子句。
 
如:
 
(select first_name,last_name from sakila.actor orderby last_name) unionall (select first_name,last_name from sakila.customer orderby last_name)
 limit 20;
会将actor中200条记录和customer中599条记录放在一个临时表中,然后在从临时表中取出前20条;
 

(select first_name,last_name from sakila.actor orderby last_name

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读