本文转载自:历时七天,史上最强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的处理性能


本文转载自:历时七天,史上最强MySQL优化总结,从此优化So Easy!

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

  1. 史上最强MySQL总结大全

    目录 一.MySQL数据库基础 1,数据库的操作 1.1.显示当前数据库 1.2 .创建数据库 1.3.使用数据库 1.4.删除数据库 2.常用数据类型 2.1.数值类型 2.2.字符串类型 2.3. ...

  2. 史上最强七种防蚊药水大比拼!看完你都震惊了!

    据广州日报:驱蚊花露水其实是农药?驱蚊花露水被曝标着农药登记号,有的还注明"微毒".能起驱蚊杀蚊作用的正是这些"微毒"物质:菊酯.驱蚊酯.避蚊胺.疾控专家称,这 ...

  3. 史上最全MySQL 大表优化方案(长文)

    转载自  史上最全MySQL 大表优化方案(长文) 当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 一.单表优化 除非单表数据未来会一直不断上涨,否则不要一开始就考虑 ...

  4. 二十万字带你入门C语言-史上最强C语言教程(汇总篇)

    一.前言 至此,史上最强C语言教程系列已经全部完成,今天是给大家来做一个汇总,笔者目前已经完成了C语言阶段的学习,一直以来感谢大家的陪伴与支持,笔者后续还会继续更新C++.数据结构.Linux.Mys ...

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

    史上最强型人养成秘籍: 90 天肥仔变型男实录[12P] 这是一篇最近很火的帖子.主人公B.K ,是一个从来没有看见过自己腹肌的 三十三岁中年普通男人,就是因为青春易逝的危机感,让他下定决心给自己一个 ...

  6. JVM面试题(史上最强、持续更新、吐血推荐)

    JVM面试题(史上最强.持续更新.吐血推荐) 文章很长,建议收藏起来慢慢读!疯狂创客圈总目录 语雀版 | 总目录 码云版| 总目录 博客园版 为您奉上珍贵的学习资源 : <尼恩Java面试宝典& ...

  7. 史上最强安全大赛:2022潮汐安全应用开发大赛

    史上最强安全大赛:2022潮汐安全应用开发大赛 01 比赛概述 02 项目概述 03 获奖情况 04 潮汐平台 7月2日,经过一周的大众投票, 2022首届潮汐安全应用开发大赛决出了总冠军以及前三甲, ...

  8. SQL初学、精通者必看:10个学生成绩查询史上最强技巧全攻略

    SQL初学.精通者必看:10个学生成绩查询史上最强技巧全攻略 本文提供了一个含有学生.成绩.课程和教师信息的完整数据库,并为读者提供了 SQL 查询练习题,还包含了练习的答案以及解析.这些题目旨在帮助 ...

  9. 史上最强女游戏程序员

    也许你听说过John Carmack 和Tim Sweeney等大牛的名字,而向来游戏工业都是阳盛阴衰,适逢国际妇女节,今天我为大家介绍游戏业界一位史上最强女游戏程序员:Corrinne Yu. 简历 ...

  10. “史上最强”BigGAN公开TensorFlow Hub demo!

    还记得前些日子轰动一时的 BigGAN 模型吗?生成对抗网络(GAN)作为当前最热门的技术之一,最近在图像生成方面的成果颇受人关注.近日,由 DeepMind 和赫瑞瓦特大学组成的科研人员公布的 Bi ...

最新文章

  1. 将人工智能模型压缩到微控制器中
  2. 自适应采样非局部神经网络的点云鲁棒操作
  3. 新一代数据中心标准化统一交换架构
  4. ES6 模块加载export 、import、export default 、import() 语法与区别,笔记总结
  5. BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组
  6. python 两阶段聚类_挑子学习笔记:两步聚类算法(TwoStep Cluster Algorithm)——改进的BIRCH算法...
  7. Lamport Logical Clock 学习
  8. Oracle over函数学习
  9. android job service,服务保活那些事(Job Service ,JobScheduler)
  10. 基于Protues的Arduino学习笔记01-Arduino UNO实验板设计
  11. web容器 Spring容器 SpringMVC容器 的关系
  12. mysql checkpoint_MySQL checkpoint深入分析
  13. kindeditor上传图片编辑框乱码问题
  14. 读取XML字符串到临时表
  15. vs2015安装vs assist 教程
  16. 蜂巢(已更名为网易云计算基础服务)计费系统架构升级之路
  17. c语言报告 实验环境怎么写,C语言实验报告
  18. 数据管理知识体系指南(第二版)-第四章——数据架构-学习笔记
  19. 2019校招秋招总结
  20. 炼数成金数据分析课程---18、降维技术(后面要重点看)

热门文章

  1. ★如何解释特修斯之船问题?
  2. 【CG原画插画教程】板绘基础如何学习
  3. java提高_最有效提高Java的10个计划
  4. OpenCV把彩色图片转换为灰度图片
  5. git rebase——分支变基及变基的风险
  6. python爬虫爬取下厨房食谱,周末聚餐真的停不下来
  7. 修改设备管理器信息,修改我的电脑系统属性,修改dxdiag信息
  8. 在iOS 14中使用带有SF Symbols 2的彩色图标
  9. 夏雨老师:告诉你初学习平面设计需要什么条件
  10. asp.net 打印html文件,关于ASP.NET页面打印技术的常用方法总结