SQL业务审核与优化
审核
什么是业务审核类似与code review评审业务Schema和SQL设计偏重关注性能是业务优化的主要入口之一 审核提前发现问题,进行优化 上线后通过监控或巡检发现问题,进行优化Schema设计审核表和字段命名是否合规字段类型,长度设计是否适当表关联关系是否合理主键,更新时间保留字段等是否符合要求约束,默认值等配置是否恰当了解业务,表数据量,增长模式数据访问模式,均衡度根据业务需求,表是否需要分区,是否有数据什么周期SQL语句审核SQL语句的执行频率表上是否有合适的索引单次执行的成本执行模式,锁情况分析关注事务上下文什么时候需要审核业务开发阶段,上线前业务版本变更,线上更新前新表和SQL上线SQL查询条件变化SQL查询频率变化业务逻辑导致现有表数据量规模变化业务发布流程SQL审核需要开发与应用运维支持充分沟通,做好必要性说明和教育工作指定业务发布流程,嵌入DBA审核环节积累经验,不断完善评审方法 慢查询
查询优化,索引优化,库表结构优化需要齐头并进。慢查询两个步骤分析:确认应用程序是否向数据库请求了大量超过需要的数据确认mysql服务器层是否在处理大量超过需要的数据记录是否向数据库请求了不需要的数据典型案例:查询不需要的记录多表关联时返回全部列总是取出全部列重复查询相同的数据mysql是否在扫描额外的记录在确定查询只返回需要的数据后,接下来应该看看查询为了返回结果是否扫描了过多的数据。mysql查询开销的三个指标:响应时间扫描的行数返回的行数这三个指标都会记录到mysql的慢日志中,索引检查慢日志记录是找出扫描行数过多的查询的好办。响应时间:执行时间和等待时间;判断一个响应时间是否是合理的值,可以使用"快速上限估计"。扫描的行数和返回的行数分析查询时,查看该查询扫描的行数是非常有帮助的。它一定程度上说明该查询找到需要的数据的效率高不高。如果发现查询需要扫描大量的数据但只返回少数的行,优化方法:使用索引覆盖扫描,把所有需要用的列都放到索引中。改变库表结构。例如使用单独的汇总表重写这个复杂的查询,让mysql优化器能够以更优化的方式执行这个查询。有的时候将大查询分解为多个小查询是有必要的。 查询执行的基础
mysql查询执行路径
mysql> show full processlist; +----+------+-----------+--------+---------+------+-------+------------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------+--------+---------+------+-------+------------------------+ | 39 | root | localhost | sakila | Sleep | 4 | | NULL | | 40 | root | localhost | sakila | Query | 0 | NULL | show full processlist | +----+------+-----------+--------+---------+------+-------+------------------------+ 2 rows in set (0.00 sec)
一条查询可以有很多种执行方式,最后都返回相同的结果。优化器的作用就是找到这其中最好的执行计划。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 | +-----------------+-------------+
1 关联子查询mysql的子查询实现得非常糟糕;最糟糕的一类查询是where条件中包含IN()的子查询语句。例如,我们希望找到sakila数据库中,演员actor_id为1,参演过的所有影片信息。很自然的,我们会按照下面的方式
mysql> select * from film where film_id in ( select film_id from film_actor where actor_id =1) \G;
select * from film where film_id in (1,23,25,106,140);
limit 20;会将actor中200条记录和customer中599条记录放在一个临时表中,然后在从临时表中取出前20条;而(select first_name,last_name from sakila.actor orderby last_name
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。