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

这些常被忽视的SQL错误用法,你知道吗

发布时间:2019-09-25 19:09:59 所属栏目:MySql教程 来源:佚名
导读:副标题#e# sql语句的执行顺序: FROM left_table ON join_condition join_type JOIN right_table WHERE where_condition GROUPBY group_by_list HAVING having_condition SELECT DISTINCT select_list ORDERBY order_by_condition LIMIT limit_number 1、LI

再检查执行计划:子查询物化后(select_type=DERIVED)参与 JOIN。虽然估算行扫描仍然为90万,但是利用了索引以及 LIMIT 子句后,实际执行时间变得很小。

  1. +----+-------------+------------+--------+---------------+---------+---------+-------+--------+----------------------------------------------------+ 
  2. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  3. +----+-------------+------------+--------+---------------+---------+---------+-------+--------+----------------------------------------------------+ 
  4. | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 15 | Using temporary; Using filesort | 
  5. | 1 | PRIMARY | u | eq_ref | PRIMARY | PRIMARY | 4 | o.uid | 1 | NULL | 
  6. | 1 | PRIMARY | p | ALL | PRIMARY | NULL | NULL | NULL | 6 | Using where; Using join buffer (Block Nested Loop) | 
  7. | 2 | DERIVED | o | index | NULL | idx_1 | 5 | NULL | 909112 | Using where | 
  8. +----+-------------+------------+--------+---------------+---------+---------+-------+--------+----------------------------------------------------+ 

8、中间结果集下推

再来看下面这个已经初步优化过的例子(左连接中的主表优先作用查询条件):

  1. SELECT a.*,  
  2.  c.allocated  
  3. FROM (  
  4.  SELECT resourceid  
  5.  FROM my_distribute d  
  6.  WHERE isdelete = 0  
  7.  AND cusmanagercode = '1234567'  
  8.  ORDER BY salecode limit 20) a  
  9. LEFT JOIN  
  10.  (  
  11.  SELECT resourcesid, sum(ifnull(allocation, 0) * 12345) allocated  
  12.  FROM my_resources  
  13.  GROUP BY resourcesid) c  
  14. ON a.resourceid = c.resourcesid 

那么该语句还存在其它问题吗?不难看出子查询 c 是全表聚合查询,在表数量特别大的情况下会导致整个语句的性能下降。

其实对于子查询 c,左连接最后结果集只关心能和主表 resourceid 能匹配的数据。因此我们可以重写语句如下,执行时间从原来的2秒下降到2毫秒。

  1. SELECT a.*,  
  2.  c.allocated  
  3. FROM (  
  4.  SELECT resourceid  
  5.  FROM my_distribute d  
  6.  WHERE isdelete = 0  
  7.  AND cusmanagercode = '1234567'  
  8.  ORDER BY salecode limit 20) a  
  9. LEFT JOIN  
  10.  (  
  11.  SELECT resourcesid, sum(ifnull(allocation, 0) * 12345) allocated  
  12.  FROM my_resources r,  
  13.  (  
  14.  SELECT resourceid  
  15.  FROM my_distribute d  
  16.  WHERE isdelete = 0  
  17.  AND cusmanagercode = '1234567'  
  18.  ORDER BY salecode limit 20) a  
  19.  WHERE r.resourcesid = a.resourcesid  
  20.  GROUP BY resourcesid) c  
  21. ON a.resourceid = c.resourcesid 

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

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

热点阅读