历时七天,史上最强MySQL优化总结,从此优化So Easy!

一、概述

1. 为什么要优化

  • 一个应用吞吐量瓶颈往往出现在数据库的处理速度上
  • 随着应用程序的使用,数据库数据逐渐增多,数据库处理压力逐渐增大
  • 关系型数据库的数据是存放在磁盘上的,读写速度较慢(与内存中的数据相比)

2. 如何优化

  • 表、字段的设计阶段,考量更优的存储和计算
  • 数据库自身提供的优化功能,如索引
  • 横向扩展,主从复制、读写分离、负载均衡和高可用
  • 典型SQL语句优化(收效甚微)

二、字段设计

1. 典型方案

①. 对精度有要求

  • decimal
  • 小数转整数

②. 尽量使用整数表示字符串(IP)

  • inet_ aton("ip‘ )
  • inet_ ntoa(num)

③. 尽可能使用not null

  • nuI数值的计算逻辑比较复杂

④. 定长和非定长的选择

  • 较长的数字数据可以使用decimal
  • char为定长(超过长度的内容将被截掉), varchar为非定长,text对内容 长度的保存额外保存而varchar对长度的保存占用数据空间

⑤. 字段数不要过多字段注释是必要的、字段命名见名思意、可以预留字段以备扩展

2. 范式

①. 第一范式:段原子性(关系型数据库有列的念,默认就符合了)

②. 第二范式:消除对主键的部分依赖(因为主键可能不止一个);使用一 个与业务无关的字段作为主键

③. 第三范式:消除对主键的传递依赖;高内聚, 如商品表可分为商品简略信息表和商品详情表两张表

三、存储引擎的选择(MyISAM和Innodb)

1. 功能差异

Innodb支持事务、 行级锁定、外健

2. 存储差异

①. 存储方式:MyISAM的数据和索弓 |是分开存储的(.MYI.MYD) , 而Innodb是存在一起的(.frm)

②. 表可移动性:可以通过移动表对应的MYI和MYD能够实现表的移动,而Innodb还有 额外的关联文件

③. 碎片空间:MyISAM删除数据时会产生碎片空间(占用表文件空间),需要定期通过optimizetable table-name手动优化。而Innodb不会。

④. 有序存储:Innodb插入数据时按照主键有序来插入。因此表中数据默认按主键有序(耗费写入时间,因为需要在b+ tree中查找插入点,但查找效率高)

3. 选择差异

①. 读多写少用MyISAM:新闻、博客网站

②. 读多写也多用Innodb:

  • 支持事务/外键,保证数据-致性、完整性
  • 并发能力强(行锁)

四、索引

1. 什么是索引

从数据中提取的具有标识性的关键字,并且有到对应数据的映射关系

2. 类型

①. 主键索引primary key:要求关键字唯一且不为null

②. 普通索引key:符合索引仅按照第一字段有序

③. 唯一索引unique key:要求关键字唯一

④. 全文索引fulltext key (不支持中文)

3. 索引管理语法

①. 查看索引

  • show create table student
  • desc student

②. 建立索引

  • 创建时指定,如first. name varchar(1 6),last name(1 6) , key name(first name,last name)
  • 更改表结构:alter table student add key/unique key/primary key/ultext key key. name(first name,last name)

③. 删除索引

  • alter table student drop key key_ name
  • 如果删除的是主键索引,并且主键自增长,则需要alter modify先取消自增长再删除

4. 执行计划explain

分析SQL执行是否用到了索引,用到了什么索引

5. 索引使用的场景

  • where:如果查找字段都建立了索引,则会索引覆盖
  • order by:如果排序字段建立了索引,而索引又是有序排列的,直接根据索引拿对应数据即可,与读取查询出来的所有数据再排序相比效率很高
  • join:如果join on的条件字段建立了索引,查找会变得高效
  • 索引覆盖:直接对索引做查找,而不去读取数据

6. 语法细节

即使建立了索引,有些场景也不一定使用

  • where id+1 = ?建议写成where id = ?-1,即保证索弓|字段的独立出现
  • like语句不要在关键字前模糊匹配,即"%keyword不会使用索引,而"keyword% 会使用索引
  • or关键两边条件字段都建立索引时才会使用索引,只要有一边不是就会做全表扫描
  • 状态值。像性别这样的状态值,-个关键字对应很多条数据,会认为使用索引比全表扫描效率还低

7. 索引的存储结构

  • btree:搜索多叉树:结点内关键字有序排列,关键字之间有一个指针,查找效率log(nodeSize,N),其中nodeSize指一 个结点内关键字数量 (这取决于关键字长度和结点大小)
  • b+ tree:由btree升级而来,数据和关键字存在一块空间,省去了由关键字到数据的映射找数据存放地的时间

五、查询缓存

1. 将select查询结果缓存起来,key为SQL语句,value为查询结果

如果SQL功能一样,但只是多个空格或略微改动都会导致key的不匹配

2. 客户端开启

query. cache. _type
  • 0-不开启
  • 1-开启,默认缓存每条select,针对某个sq不缓存: select sql-no-cache
  • 2-开启,默认都不缓存,通过select sql-cache制定缓存哪-个条

3. 客户端设置缓存大小

query_ cache .size

4. 重蛋缓存

reset query cache

5. 缓存失效

日对数据表的改动会导致基 于该数据表的所有缓存失效(表层面的管理)

六、分区

1. 默认情况下一张表对应一组存储文件,但当数据量较大时(通常千万条级别)需要将数据分到多组存储文件,保证单个文件的处理效率

2. partition by分区函数(分区字段)(分区逻辑)

  • hash-分区字段为整型
  • key-分区字段为字符串
  • range-基于比较,只支持less than
  • list-基于状态值

3. 分区管理

  • 创建时分区:create table article0 partition by key(title) partitions 10
  • 修改表结构:alter table article add partition(分区逻辑)

4. 分区字段应选择常用的检素字段,否则分区意义不大

七、水平分割和垂直分割

1. 水平

多张结构相同的表存储同一类型数据

单独一张表保证id唯一性

2. 垂直

分割字段到多张表,这些表记录是一对应关系

八、集群

1. 主从复制

①. 首先手动将slave和master同步一下

  • stop slave
  • master导出数据到slave执行一遍
  • show master status with read lock记录File和Position
  • 到slave.上change master to

②. start slave查看Slave IO Running和Slave SQL _Running,必须都为YES

③. master可读可写,但slave只能读,否则主从复制会失效需要重新手动同步

④. mysqlreplicate快速配置主从复制

2. 读写分离(基于主从复制)

①. 使用原stcConecton

WriteDatabase提供写连接

ReadDatabase提供读连接

②. 借助Sping AOP和Aspec实现数据源动态切换

  • RoutingDataSourcelmpl extends AbstractRoutingDataSource,重写determineDatasource,注入到SqISessionFactory, 配置defaultTargetDatasource和targetDatasource (根据determineDatasource的返回值选择 具体数据源value-ref)
  • DatasourceAspect切面组件,配置切入点@Pointcut aspect0 (所有DAO类的所有方法),配置前置增强@Before(" aspect0") before(Joinpoint point), 通过point.getSignature.getName获取方法名,与METHOD TYPE MAP的前缀集合比对,将write/read设置到当前线程上(也是接下来要执行DAO方法的线程,前置增强将其拦截下来了)
  • DatasourceHandler,使用ThreadLocal在前置通知中将方法要使用的数据源绑定到执行该方法的线程上,执行方法要获取数据源时再根据当前线程获取

3. 负载均衡

算法

  • 轮询
  • 加权轮询
  • 依据负载情况

4. 高可用

为单机服务提供一个冗余机

  • 心跳检测
  • 虚IP
  • 主从复制

九、典型SQL

1. 线上DDL

为了避免长时间表级锁定

  • copy策略,逐行复制,记录复制期间旧表SQL日志重新执行
  • mysq|5.6 online ddl,大大缩短锁定时间

2. 批量导入

①. 先禁用索引和约束,导入之后统一建立

②. 避免逐条事务

innodb为了保证一致性,默认为每条SQL加事务(也是要耗费时间的),批量导入前应手动建立事务,导入完毕后手动提交事务。

3. limit offset,rows

避兔较大的offset (较大页码数)

offset用来跳过数据,完全可以用过滤筛选数据,而不是查出来之后再通过offset跳过

4. select *

尽量查询所需字段,减少网络传输延时(影响不大)

5. order by rand()

会为每条数据生成一个随机数最后根据随机数排序,可以使用应用程序生成随机主键代替

6. limit 1

如果确定了仅仅检索一条数据,建议都加上limit 1

十、慢查询日志

1. 定位查询效率较低的SQL,针对性地做优化

2. 配置项

  • 开启slow_ query. log
  • 临界时间long_ query. time

3. 慢查询日志会自己记录超过临界时间的SQL,并保存在datadir下的xxx-slow.log中

十一、Profile

1. 自动记录每条SQL的执行时间和具体某个SQL的详细步骤花费的时间

2. 配置项日

开启profiling

3. 查看日志信息show profiles

4. 查看具体SQL的详细步骤花费的时间日

show profiles for query Query_ ID

十二、典型的服务器配置

1. max_ connections, 最大客户端连接数

2. table open cache, 表文件缓存句柄数,加快表文件的读写

3. key_ buffer. _size, 索引缓存大小

4. innodb_ buffer. pool size, innodb的缓冲池大小,实现innodb各种功能的前提

5. innodb file per_ table,每个表一个ibd文件, 否则innodb共享 表空间

十三、压测工具MySQLSlap

1. 自动生成sq|并执行来测试性能

myqslap -a-to-generate sql -root -root

2. 并发测试

mysqlslap --auto-generate-sql --concurrency= 100 -uroot -proot,模拟100个客户端执行sql

3. 多轮测试,反应平均情况

mysqlslap --auto-generate-sql --concurrency= 100 --interations=3 -uroot -proot,模拟100个客户端执行sql.执行3轮

4. 存储引擎测试

  • --engine=innodb:mysqlslap --auto-generate-sql --concurrency= 100 --interations=3 -- engine-innodb -uroot -proot,模拟100个客户端执行sql.执行3轮,innodb的处理性能
  • -- engine= myisam:mysqlslap -- auto-generate-sql --concurrency= 100 --interations=3 --engine-innodb -uroot -proot,模拟100个客户端执行sql.执行3轮,myisam的处理性能

原文地址:https://blog.51cto.com/14637764/2466432

时间: 2024-10-24 00:15:23

历时七天,史上最强MySQL优化总结,从此优化So Easy!的相关文章

史上最强型人养成秘籍: 90 天肥仔变型男实录

史上最强型人养成秘籍: 90 天肥仔变型男实录[12P] 这是一篇最近很火的帖子.主人公B.K ,是一个从来没有看见过自己腹肌的三十三岁中年普通男人,就是因为青春易逝的危机感,让他下定决心给自己一个交代!于是用了九十天,他做到了!减脂和塑身计划从2014年3 月15日开始到6月25日结束,从一个非典型性胖子.微胖界翘楚.土圆肥代表,到八块腹肌霸气外露,仅仅90天. 前几天在机场,遇见一个三四个月没见的小姐妹,在她面前半天没认出我.这样的情况,近期已经第三次了.因为这个原因,我不得已又去拍了新的证

史上最强】网上所有的Axure元器件、UI、8.0安装包汉化包资源汇总

史上最强]网上所有的Axure元器件.UI.8.0安装包汉化包资源汇总        目前产品经理工具中应该最火的就是axure了,简直就是人人必备.确实,在实现一些复杂的交互上,axure很管用,但是也有缺点,就是元器件不够多,很多要自己画,不美观.今天,8kvv就给大家整理了现有axure的元器件.Axure8.0.axure汉化包.苹果iOSUI及安卓5.0安卓6.0UI.很全啦! 大家慢慢欣赏哦! 列举下为大家整理的网上所有的Axure的实用资源(下载地址在最后),包括: 1.Axure

【史上最强JavaSE笔记】之数组篇

各位程序猿,各位攻城狮,各位蜥蜴鸥以及各位棕鲸鲤们~~大家好,我是潘师傅,欢迎大家收看由我为你们带来的[史上最强JavaSE笔记]系列,其实也可以叫[嘻哈JavaSE笔记]的,第一次在博客园发帖,想想还真是有点小激动呢,各位求支持呀,哈哈,那么回归正题,我把自己之前学习积累的笔记拿出来跟大家分享一下,方便大家更好的理解和复习,希望能够对大家有所帮助哈,这次发的是JavaSE方面数组篇的,内容不一定全面哦,欢迎大家前来留言交流哈,不足的地方还望大家多多指出和指导哈~(由于首次发文章,布局可能比较乱

史上最强实名制来袭!究竟切中了谁的要害?

对常在互联网上蹦跶的你,现在只想说三个字:实名制!近日,bilibili(B站)发布公告称,"应国家相关政策规定要求,从7月5日开始,UP主(视频创作者或上传者)上传视频内容(包括新增.编辑.换源等)需通过实名验证,方可编辑视频稿件".而这,可以看做是史上最强实名制的一部分. 事实上,近段时间以来,实名制是一直是网上热议的争议性话题之一.是否需要实名制.是否对部分用户的隐私权构成威胁.是否影响言论自由及互联网开放的本质精神.实名制究竟有多大的威慑力--史上最强实名制的全面来袭,究竟切中

史上最强算法论战:请不要嘻哈,这是哈希[下]

史上最强算法论战:请不要嘻哈,这是哈希[下] 欢迎个人转发朋友圈,机构及媒体转载需在开篇声明,转自微信公号“知象科技” 论战主角之一龙博:知象科技CEO,欲了解龙博及知象科技,请点击文末“阅读原文”. 这是“美丽互联”微信群里的一次算法论战,感谢书记员硅谷寒(梁寒)精彩的说书般的整理. 书接上文 一夜过去了…孤独虎精神抖擞的回来了! [书记员注:上集说到独孤虎被龙博两次判零分,已经到了精神分裂的边缘.于是他决定回家休养生息,以图再战.果不其然,第二天,独孤虎首先跳出来,带来了他的第四种方案.我们

翻翻git之---史上最强的图片选择器 GalleryFinal(顺带附下麦麦,当当的近照)

转载请注明出处:王亟亟的大牛之路 技术内容在P2,P1是废话可以跳过 P1:(开胃菜) 最近手头上工作的事差不多告一段落了,可以把更多的精力花在学习上了,还是会继续翻git这部分的文章(搬运工),然后准备整整一些之前没接触过的知识点(具体学什么没想好,等会看看去) 先上一下家里宝贝的近照 P2:(正菜) 今天上的是一个自称是"史上最强的图片选择器" GalleryFinal 话不多说先看看效果 作者几乎实现了我们平时所需的"皂片"选择器的所有功能,还带有一定的编辑和

喜欢,就要说出来,别等错失后才觉醒!史上最强告白!

喜欢,就要说出来,别等错失后才觉醒!史上最强告白!! 2016-08-06 亚谷科技 下辈子也要找到你 孙露 - 孙情流露 人一生会错过很多东西, 回得了过去,回不了当初. 关于爱情 喜欢 就要大声的说出来, 别再去等一个人.或者等一个故事. <偶像版> <太阳的后裔>第一集里男主就喜欢上了女主. -- “和我一起看电影吧?快回答,没时间了,好还是不好?” -- “好!” -- “那就这样说定了!” 喜欢就别矫情   <剧情版> “不好意思,刚认识就喜欢你!” 无论结果

【插件】史上最强编辑器通用ctags插件OpenCTags使用指南v1.2--开发者必备

Changes Log: v1.2.0 2011-12-4 支持Java编写的可以设置用户配置的编辑工具 增加当前文件类查找Tags功能 增加设置当前目录参数 完善多种主流轻量级编辑器的配置 v1.1.0 2011-11-26 完善提示窗口的显示样式 编辑器配置使用Json格式配置文件,方便定制到自己喜欢的编辑器,主流编辑器一网打尽 v1.0.4 2011-11-21 支持提示窗口拖动,按住鼠标右键,即可拖拖拖[上一版本为鼠标左键] 增加回车键功能,按下可以会自动打开对应的文件并定位到对应的位置

豆瓣看到一个史上最强最犀利骂人帖

豆瓣看到一个史上最强最犀利骂人帖 http://beijing.edeng.cn/xinxi/179414813.htmlhttp://beijing.edeng.cn/xinxi/179414852.htmlhttp://beijing.edeng.cn/xinxi/179414847.htmlhttp://beijing.edeng.cn/xinxi/179414862.htmlhttp://beijing.edeng.cn/xinxi/179414872.htmlhttp://beijin