关于SQL优化这些你了解吗?

关于SQL优化这些你了解吗?

背景

  在当今这个互联网的时代无非要解决两大难题,其一是信息安全,其二就是数据的存储。而信息安全则是在数据存储的基础之上。一个公司从刚开始成立到发展成一个有上百人甚至上千人团队的时候,公司的业务量是呈上升趋势,客户及用户也会愈来愈多;以前设计的表结构可能会显得不合理,表与表之间的联系没有一个稳定的业务功能划分,从而表现出来的是相关表的备用字段愈来愈不够用甚至新加字段,最坏的状况就是不一样业务表之间会有数据冗杂。从而暴露出一些设计的问题,这也就是SQL优化点之一:数据库表结构设计的合理性。近年来大数据愈来愈火,而大数据也是为了解决数据的存储的手段之一,其目的是从海量的数据中收集到有价值的信息而后存储到数据库中,由于数据量大传统的数据库没法储存那么多的信息因此须要分析有价值的信息后再作决定是否持久化。html

优化点数据库

  • 前提必备知识

  学会是用explain关键词查看SQL语句性能,explain好像是从MYSQL5.6.3开始支持 select、update、delete语句分析,以前只支持select语句。如今咱们广泛都是用5.7,因此的话不须要太担忧。这里的话不详细讲如何解读explain输出的性能信息。请参看博客文档:《MySQL优化之Explain命令解读》缓存

  • 优化之一 - 从数据库设计方面考虑
  1. 表与表之间的业务联系要明确:表之间实际上是有业务联系的,好比:class(primary key:class_id,全部班级信息表)、student(primary key:student_num,全部学生信息表)、student_class(primary key:stu_class_id,全部学生所在班级信息表)着三张表,若是如今须要一张老师对应哪一个班级的班主任的信息表;那么此时正确的方法是:新建 teacher、teacher_class表,而不是直接把老师的信息插入到student表中而后用一个字段来标识是老师仍是学生。可能你看到这个你会想 “我确定会按正确的那种方式啊”,可是这只是举一个例子,其实在实际项目开发过程当中表与表结构每每不会那么单一,这个时候你就会犯错误而用字段标识。可是也不能说是不能用字段标识,这个要看字段标识的两种信息对应的业务是否有交叉点来取舍。
  2. 表字段尽可能使用数值型:由于数值型字段在MySQL底层应用的时候相比string类型的话性能更好;具体为何性能更好就须要了解MySQL底层机制了,反正记住这点就好。
  3. 属性尽可能使用定长:以减小占用储存空间;若是你定义了一个 order_id varchar(32) ,当在存储的时候有一条记录的order_id=20180910242360,此时order_id实际占用了14个字节可是这个字段的属性长度是32,因此还有18个字节长度是无用的但却占用着内存空间。
  4. 创建合理的索引:索引就是用某种数据结构来查找对应的信息,从而减低时间复杂度提升查找效率。创建索引的前提也要明确,综合考虑再打算是否须要创建索引,毕竟索引是须要占用存储空间的,有时候牺牲的空间却换不回时间。
     
  • 优化之二 - 从SQL语句优化方面考虑

  1. 尽可能将要输出的字段写出来;不要使用 select * from where xxxxx ;这种形式的语句。我在这测试时是使用*代替,可是记住在生产环境上尽可能将字段替代*。安全

  2. 合理使用连表查询;不只是表的链接须要较大的内存消耗另一方面若是表设计的不是很合理也会致使索引无效从而形成极坏的结果。性能优化

  3. 查询的时候要注意是否走索引:假如你在name列创建了一个 name_index索引,查询你使用 name Like'%xxxx' 或者 name Like'%xxxx%' 这种模糊查询,那么此时可能就不会走索引;你应该这样  name Like'xxxx%' 。如下就是实际的一个例子:  数据结构

  创建索引:架构

-- 为cust_third_acct 创建一个普通索引
alter table
cust_info
add index cust_third_acct_index(cust_third_acct);

 

  a:经过SQL查询信息: select * from sp_tunnel_user where cust_third_acct like'0200%';   如下就是知足查询条件的部分信息并发


  b:分析Like'%xxxx%'的查询性能: select * from sp_tunnel_user where cust_third_acct like'%0200%';  经过Explain性能分析命令能够知道:在这种查询条件下并无执行索引,type=all代表该语句执行的时候进行的是全表扫描;虽然咱们在 cust_third_acct  这个字段创建了索引,可是 possible_keys=null 则说明了 用 like'%0200%' 这种形式的条件是必定没法使用到  cust_third_acct_index  这个索引。(其余字段的解析请参照《MySQL优化之Explain命令解读》这篇文章,这里不作过多的分析)。数据库设计

    

  c:分析Like'xxxx%'的查询性能: select * from sp_tunnel_user where cust_third_acct like'0200%';  与b查询语句相比这个查询的  possible_keys=cust_third_acct_index  ,这说明这个语句可能会用到 cust_third_acct_index 这个索引,可是key=null代表在实际的执行过程当中并无用到  cust_third_acct_index  索引;刚才咱们也说了这种条件查询只是可能会走索引可是不必定发生,这个跟MySQL的存储引擎相关,可是咱们使用的时候尽可能以这种方式去查询。分布式

  

  4. 使用索引遵循最佳左前缀特性,创建联合索引的时候将经常使用的属性放在左边。好比:咱们需在在一张表的 cust_id 和 cust_tp 创建一个联合索引 cust_id_type,设定cust_id(不是惟一) 是比较经常使用的那么咱们就将cust_id放在左边。

  创建联合索引:

-- 为cust_id与cust_tp创建一个联合索引
alter table
cust_info
add index  cust_id_type(cust_id,cust_tp);

 

  5.使用符合索引的时候须要注意:使用联合索引须要从左往右不间断,索引才会生效,也就是说联合索引使用的时候必需要连续但不要求所有使用。如:以上4咱们创建了一个  cust_id_type  索引,当咱们在使用的时候若是where条件中只使用了 cust_id,那么也会走索引;若是where条件中只使用了 cust_tp,那么这条语句不会走索引,如下就是一个实例:

  a:select * from sp_tunnel_user where cust_id='8888888888' and cust_tp='04';  当查询条件用到cust_id与cust_tp两个字段而且cust_id在前面的时候,就会用到联合索引;经过 key=cust_id_type能够看到实际执行过程当中是用到索引了的。

 

  b:select * from sp_tunnel_user where cust_id='8888888888' ;  当查询条件只用到cust_id一个字段时,也用到了联合索引;经过 key=cust_id_type能够看到实际执行过程当中是用到索引了的,这就是左前缀原则。

 

  c:select * from sp_tunnel_user where cust_tp='04' ;  当查询条件只用到cust_tp一个字段时,但却没有用到索引;经过 key=null 能够看到实际执行过程并无用到索引,这也是左前缀原则。

 

  • 优化之三 - 读写分离与分库分表

  当数据量达到必定的数量以后,限制数据库存储性能的就再也不是数据库层面的优化就可以解决的;这个时候每每采用的是读写分离与分库分表同时也会结合缓存一块儿使用,而这个时候数据库层面的优化只是基础。读写分离适用于较小一些的数据量;分表适用于中等数据量;而分库与分表通常是结合着用,这就适用于大数据量的存储了,这也是如今大型互联网公司解决数据存储的方法之一。至于怎么读写分离、怎么分表、怎么分库,这里不作过多的阐述后续文章会有相关知识分享。

顺便在此给你们推荐一个Java架构方面的交流学习群:698581634,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系,主要针对Java开发人员提高本身,突破瓶颈,相信你来学习,会有提高和收获。在这个群里会有你须要的内容  朋友们请抓紧时间加入进来吧。

相关文章
相关标签/搜索