加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

Mysql应用Mysql - 性能优化之子查询

发布时间:2020-12-12 00:48:08 所属栏目:MySql教程 来源:网络整理
导读:《Mysql应用Mysql - 性能优化之子查询》要点: 本文介绍了Mysql应用Mysql - 性能优化之子查询,希望对您有用。如果有疑问,可以联系我们。 导读:当Mysql Server的连接线程接收到Client发送过来的SQL请求后,会经过一系列的分解Parse,进行相应的分析,然后Mysq

《Mysql应用Mysql - 性能优化之子查询》要点:
本文介绍了Mysql应用Mysql - 性能优化之子查询,希望对您有用。如果有疑问,可以联系我们。

导读:当Mysql Server的连接线程接收到Client发送过来的SQL请求后,会经过一系列的分解Parse,进行相应的分析,然后Mysql会通过查询优化器模...

MYSQL实例当Mysql Server的连接线程接收到Client发送过来的SQL请求后,然后Mysql会通过查询优化器模块,根据该Sql所涉及到的数据表的相关统计信息进行计算分析. 然后在得出一个Mysql自认为最合理最优化的数据访问方式,也就是我们常说的"执行计划",然后根据所得到的执行计划通过调用存储引擎接口来获取相应数据. 再对存储引擎返回的数据进行相关的处理,并一Client端所要求的格式作为结果集,返回给Client.

MYSQL实例注 : 这里所说的统计数据,是我们通过 Analyze table命令通知Mysql对表的相关数据作分析之后,所获取到的一些数据统计量. 这些数据对Mysql优化器而言是非常重要的,优化器所生成的执行计划的好坏,主要是由这些统计数据所决定的.

MYSQL实例1. 建表
?

  1. create?table?User(?
  2.   Id?int?not?null?PRIMARY?key?auto_increment?,?
  3.   NickName?varchar(50)?comment?'用户昵称',?
  4.   Sex?int?comment?'性别',?
  5.   Sign?varchar(50)?comment?'用户签名',?
  6.   Birthday?datetime?comment?'用户生日',?
  7.   CreateTime?datetime?comment?'创建时间'?
  8. )?default?charset=utf8?comment?'用户表';?
  9. ?
  10. create?table?UserGroup(?
  11.   Id?int?not?null?PRIMARY?key?auto_increment?,?
  12.   UserId?int?not?null?comment?'user?Id',?
  13.   GroupId?int?not?null?comment?'用户组Id',?
  14.   CreateTime?datetime?comment?'创建时间',?
  15.   --?key?index_groupid(GroupId)?using?btree,?
  16.   key?index_userid(groupid,?UserId)?using?btree?
  17. )?default?charset=utf8?comment?'用户组表';?

MYSQL实例2. 准备数据

?

  1. var?conStr?=?ConfigurationManager.ConnectionStrings["ConStr"].ToString();?
  2. using?(IDbConnection?conn?=?new?MySqlConnection(conStr))?
  3. {?
  4. ????Stopwatch?watch?=?new?Stopwatch();?
  5. ????var?sql?=?string.Empty;?
  6. ????var?names?=?new?string[]?{?"非",?"想",?"红",?"帝",?"德",?"看",?"梅",?"插",?"兔"?};?
  7. ????Random?ran?=?new?Random();???
  8. ????var?insertSql?=?@"?insert?into?User(NickName,Sex,Sign,?Birthday,?CreateTime)?values(@NickName,@Sex,@Sign,?@Birthday,?@CreateTime);??
  9. ????INSERT?INTO?usergroup??(UserId,??GroupId,??CreateTime?)??VALUES?(LAST_INSERT_ID()?,???@GroupId,??@CreateTime);";?
  10. ????watch.Start();?
  11. ????if?(conn.State?==?ConnectionState.Closed)?
  12. ????{?
  13. ????????conn.Open();?
  14. ????}?
  15. ?
  16. ????var?tran?=?conn.BeginTransaction();?
  17. ????for?(int?i?=?0;?i?<?100000;?i++)?
  18. ????{?
  19. ????????var?param?=?new?{?NickName?=?names[ran.Next(9)]?+?names[ran.Next(9)]?+?i,?Sign?=?names[ran.Next(9)]?+?names[ran.Next(9)],?CreateTime?=?DateTime.Now,?Birthday?=?DateTime.Now.AddYears(ran.Next(10,?30)),?Sex?=?i?%?2,?GroupId?=?ran.Next(1,?100)?};?
  20. ????????conn.Execute(insertSql,?param,?tran);?
  21. ????}?
  22. ????tran.Commit();?
  23. ?
  24. ????conn.Dispose();?
  25. ????watch.Stop();?
  26. ????Console.WriteLine(watch.ElapsedMilliseconds);?
  27. }?

MYSQL实例这里我插入了5000条数据,group分了99个组,随机的.?

MYSQL实例?

MYSQL实例3. 查询sql

?

  1. explain?
  2. select?user.id,?user.nickname?from?usergroup??
  3. left?join?user??on?usergroup.UserId?=?user.Id?
  4. where??usergroup.groupid?=?1??
  5. order?by?usergroup.UserId?desc?
  6. limit?100,?20;?
  7. ?
  8. ?explain?
  9. select?user.id,?user.nickname?
  10. from?(select?id,?userid?from?usergroup?where?groupid?=?1?order?by?userid?limit?100,?20)?t?
  11. left?join??user?on?t.UserId?=?user.id?;?
  12. ?
  13. ?explain?
  14. select?user.id,?user.nickname?
  15. from?(select?id,?userid?from?usergroup?where?groupid?=?1?order?by?userid?)?t?
  16. left?join??user?on?t.UserId?=?user.id??
  17. limit?100,?20;?

MYSQL实例第二句和第三句都使用到了子查询,不同之处再与,第二句是先得到20条数据,然后以此来与user表关联的

MYSQL实例4. 分析

MYSQL实例100000条数据情况下 :?

MYSQL实例先看第一句

Mysql - 性能优化之子查询



再看第二句

Mysql - 性能优化之子查询



第三句

Mysql - 性能优化之子查询


从上面三幅图看,好像能看出点什么了.

MYSQL实例首先看他们的 rows,第二句最多,加起来有1000多了,另两句加起来都是996. 但是我想说的是,这里并不是看rows的和是多少. 正确的方式是,从id大的语句开始看,id相同的语句,从上到下依次执行.

MYSQL实例那先看第二句的id=2的语句和第一句的id=1的语句,一模一样的. 他们都是从usergroup表中筛选数据,并且能得到相同的结果集A.

MYSQL实例看来他们都是基于相同的结果集去进行操作,接下来就有区别了.

MYSQL实例先看第一句,再结果集A的基础上,去左连接表user,并筛选出最后的数据,返回给客户端.

MYSQL实例那第二句呢,是在A的基础上,再次筛选数据,得到需要的数据,然后拿这些数据,去与user表左连接,得到最终结果.

MYSQL实例从上面来看,执行计划中,第二种执行计划,更加高效.?

MYSQL实例?如果能够通过子查询,大幅度缩小查询范围,可以考虑使用子查询语句.?

MYSQL实例
?

(编辑:李大同)

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

    推荐文章
      热点阅读