目录树

  • 背景
  • 优化点
    1. 前提必备知识
    2. 优化之一 - 从数据库设计方面考虑

    3. 优化之二 - 从SQL语句优化方面考虑

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

背景

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


优化点

  • 前提必备知识

  学会是用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%' 。以下就是实际的一个例子:  

  建立索引:

  1. -- cust_third_acct 建立一个普通索引
    alter table
  2. cust_info
  3. 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放在左边。

  建立联合索引:

  1. -- cust_idcust_tp建立一个联合索引
    alter table
  2. cust_info
  3. 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='' and cust_tp='';  当查询条件用到cust_id与cust_tp两个字段并且cust_id在前面的时候,就会用到联合索引;通过 key=cust_id_type可以看到实际执行过程中是用到索引了的。

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

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

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

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

关于SQL优化这些你了解吗?的更多相关文章

  1. SQL优化案例—— RowNumber分页

    将业务语句翻译成SQL语句不仅是一门技术,还是一门艺术. 下面拿我们程序开发工程师最常用的ROW_NUMBER()分页作为一个典型案例来说明. 先来看看我们最常见的分页的样子: WITH CTE AS ...

  2. sql 优化

    1.选择最有效率的表名顺序(只在基于规则的优化器中有效): oracle的解析器按照从右到左的顺序处理 from 子句中的表名,from子句中写在最后的表(基础表driving table)将被最先处 ...

  3. SQL 优化总结

    SQL 优化总结 (一)SQL Server 关键的内置表.视图 1. sysobjects         SELECT name as '函数名称',xtype as XType  FROM  s ...

  4. (转)SQL 优化原则

    一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用 系统提交实际应用后,随着数据库中数据的增加,系 ...

  5. sql优化阶段性总结以及反思

    Sql优化思路阶段性心得: 这段时间的优化做了好几个案例,其实有很多的类似点,都是好几张大表的相互连接,然后执行长达好几个小时,甚至都跑不出来. 自己差不多的思路就是Parallel full tab ...

  6. mysql sql优化实例

    mysql sql优化实例 优化前: pt-query-degist分析结果: # Query 3: 0.00 QPS, 0.00x concurrency, ID 0xDC6E62FA021C85B ...

  7. SQL优化技巧

    我们开发的大部分软件,其基本业务流程都是:采集数据→将数据存储到数据库中→根据业务需求查询相应数据→对数据进行处理→传给前台展示.对整个流程进行分析,可以发现软件大部分的操作时间消耗都花在了数据库相关 ...

  8. ORACLE常用SQL优化hint语句

    在SQL语句优化过程中,我们经常会用到hint,现总结一下在SQL优化过程中常见Oracle HINT的用法: 1. /*+ALL_ROWS*/ 表明对语句块选择基于开销的优化方法,并获得最佳吞吐量, ...

  9. SQL优化有偿服务

    本人目前经营MySQL数据库的SQL优化服务,100块钱一条.具体操作模式 其中第一条,可以通过在微信朋友圈转发链接中的信息(http://www.yougemysqldba.com/discuz/v ...

  10. 【MySQL】SQL优化系列之 in与range 查询

    首先我们来说下in()这种方式的查询 在<高性能MySQL>里面提及用in这种方式可以有效的替代一定的range查询,提升查询效率,因为在一条索引里面,range字段后面的部分是不生效的. ...

随机推荐

  1. Luogu1261: 服务器储存信息问题

    题面 传送门 Sol 我们可以考虑每种\(rank\)的点\(u\)会被哪些点\(v\)感兴趣 如果\(dis[u][v]<\)所有满足\(rank\)大于\(rank[u]\)的点到\(v\) ...

  2. CSS3弹性盒布局

    使用自适应的窗口弹性盒布局 可以使div总宽度等于浏览器宽度,而且可以随着浏览器的改变而改变. <!DOCTYPE html> <html lang="zh-CN" ...

  3. Java BeanUtils 组件 使用

    1. BeanUtils组件 1.1 简介 程序中对javabean的操作很频繁, 所以apache提供了一套开源的api,方便对javabean的操作!即BeanUtils组件. BeanUtils ...

  4. Scrum----学习心得

    Scrum学习心得 什么是敏捷开发? 敏捷开发(Agile Development)是一种以人为核心.迭代.循序渐进的 开发方法.它不是一门技术,它是一种开发方法,也就是一种软件开发的流程,它会指导我 ...

  5. sqlserver中循环生成记录

    declare @i int set @i=1 while(@i<=10) begin INSERT INTO [BMData].[dbo].[QueryBlackListLogs] ([ID] ...

  6. C# FTP操作类(获取文件和文件夹列表)

    一.如何获取某一目录下的文件和文件夹列表. 由于FtpWebRequest类只提供了WebRequestMethods.Ftp.ListDirectory方式和WebRequestMethods.Ft ...

  7. SVNKit学习——使用低级别的API(ISVNEditor接口)直接操作Repository的目录和文件(五)

      本文是参考官方文档的实现,官方wiki:https://wiki.svnkit.com/Committing_To_A_Repository 本文核心使用的是ISVNEditor这个接口直接对Re ...

  8. 【Leetcode】【Medium】Remove Duplicates from Sorted Array II

    Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For exampl ...

  9. 【Leetcode】【Medium】Gas Station

    There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You ...

  10. Python学习---Python下[元组]的学习

    元组是不可变的, 用小括号()定义,而且一旦定义 ,不可变[类型是tuple] [元组看做一个整体,不可拆分,不可赋值,但可以全部重新赋值] 通过圆括号,用逗号分隔,常用在使语句或用户定义的函数能够安 ...