SQL业务审核与优化

发布时间:2020-08-10 16:21:19 作者:ilydba
来源:ITPUB博客 阅读:138
转自http://www.cnblogs.com/Aiapple/p/5697229.html

审核

 
什么是业务审核
          审核提前发现问题,进行优化
          上线后通过监控或巡检发现问题,进行优化
 
Schema设计审核
 
SQL语句审核
 
什么时候需要审核
 
业务发布流程
 
慢查询

 
查询优化,索引优化,库表结构优化需要齐头并进。
 
慢查询两个步骤分析:
 
是否向数据库请求了不需要的数据
典型案例:
 
mysql是否在扫描额外的记录
在确定查询只返回需要的数据后,接下来应该看看查询为了返回结果是否扫描了过多的数据。
 
mysql查询开销的三个指标:
 
这三个指标都会记录到mysql的慢日志中,索引检查慢日志记录是找出扫描行数过多的查询的好办。
 
响应时间:执行时间和等待时间;
判断一个响应时间是否是合理的值,可以使用"快速上限估计"。
 
扫描的行数和返回的行数
分析查询时,查看该查询扫描的行数是非常有帮助的。它一定程度上说明该查询找到需要的数据的效率高不高。
 
如果发现查询需要扫描大量的数据但只返回少数的行,优化方法:
 
有的时候将大查询分解为多个小查询是有必要的。
 
查询执行的基础

 
mysql查询执行路径
 SQL业务审核与优化


SQL业务审核与优化
 
  1. 客服端发送一条查询给服务器
  2. 服务器先检查缓存。如果命中缓存,则立刻返回结果。否则进入下一阶段。
  3. 服务器端进行SQL解析,预处理,再由优化器生成对应的执行计划。
  4. mysql根据优化器生成的执行计划,调用存储引擎的API来执行查询。
  5. 将结果返回给客户端
 
 
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 | +-----------------+-------------+


这个结果表示mysql优化器认为大概需要做1040个数据页的随机查找才能完成上面的查询。这是根据一系列的统计信息计算得来的:每个表或者索引的页面个数,索引的基数(索引中不同值的数量),索引和数据行的长度,索引分布情况。
 
优化器在评估成本的时候并不考虑任何层面的缓存,它假设读取任何数据都需要一次磁盘I/O。
 
mysql优化器选错执行计划的原因:
 
 
优化策略:
 
mysql能够处理的优化类型
 
在查询中添加hint,提示优化器,
 
优化器的局限性

 
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;


我们一般认为,mysql会首先将子查询的actor_id=1的所有film_id都找到,然后再去做外部查询,如
 
select * from film where film_id in1,23,25,106,140);


然而,mysql不是这样做的。
mysql会将相关的外层表压到子查询中,它认为这样可以更高效率地查找数据行。
 
当然我们可以使用连接替代子查询重写这个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) unionallselect 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
推荐阅读:
  1. sql 优化
  2. 说说如何做oracle的SQL审核呢

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

sql 业务 优化

上一篇:市场竞争激烈,网站服务器无法连接可能是在被攻击?

下一篇:Oracle 数据泵终止任务

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》