[MySQL] 02- Optimisation solutions
前言
一、资源
MySQL 对于千万级的大表要怎么优化? - MySQL - 知乎【方法论】
MySQL大表优化方案【一些优化的细节操作】
MySQL大表优化方案【一些优化的细节操作】
分布式数据库下子查询和join等复杂sql如何实现?【分布式数据库相关】
二、未来计划
本篇内容只是大纲,未来对本文中提到的细节还需一一实践并总结。
哪种类型的业务不需要关系型数据库,NOSQL就可以?
基于hadoop、spark构建OLAP系统,采用redis来做缓存,怎么搞?
策略
一、基本六步骤
- sql and index
- memcached, redis
- 主从复制,读写分离
- MySQL分区表
- 垂直拆分(分布式)
- 水平切分
二、详情
MYSQL数据库 一般都是按照这个步骤去演化的,成本也是由低到高;
第一优化,sql和索引;
第二加缓存,memcached,redis;
第三以上都做了后,还是慢,就做主从复制或主主复制,读写分离,可以在应用层做,效率高,也可以用三方工具,第三方工具推荐360的atlas,其它的要么效率不高,要么没人维护;
|-- Goto: MySQL主从复制(Master-Slave)实践【不错,结尾引用也不错】
第四如果以上都做了还是慢,mysql自带分区表,先试试这个,对你的应用是透明的,无需更改代码,但是sql语句是需要针对分区表做优化的,sql条件中要带上分区条件的列,从而使查询定位到少量的分区上,否则就会扫描全部分区,另外分区表还有一些坑,在这里就不多说了;
第五如果以上都做了,那就先做垂直拆分,其实就是根据你模块的耦合度,将一个大的系统分为多个小的系统,也就是分布式系统;
第六才是水平切分,针对数据量大的表,这一步最麻烦,最能考验技术水平,要选择一个合理的sharding key,为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,sql中尽量带sharding key,将数据定位到限定的表上去查,而不是扫描全部的表;
|-- Goto: 关于数据库的水平切分和垂直切分的一些概念
三、SQL优化
- SQL优化很重要
有人也许要说第一步优化sql和索引这还用说吗?的确,大家都知道,但是很多情况下,这一步做的并不到位,甚至有的只做了根据sql去建索引,根本没对sql优化(中枪了没?),除了最简单的增删改查外,想实现一个查询,可以写出很多种查询语句,不同的语句,根据你选择的引擎、表中数据的分布情况、索引情况、数据库优化策略、查询中的锁策略等因素,最终查询的效率相差很大;
- 技术、业务层面优化
优化要从整体去考虑,有时你优化一条语句后,其它查询反而效率被降低了,所以要取一个平衡点;即使精通mysql的话,除了纯技术面优化,还要根据业务面去优化sql语句,这样才能达到最优效果;你敢说你的sql和索引已经是最优了吗?
- 数据库俩引擎比对
MYISAM 和 INNODB 是Mysql数据库提供的两种存储引擎。两者的优劣可谓是各有千秋。INNODB会支持一些关系数据库的高级功能,如事务功能和行级锁,MYISAM不支持。MYISAM的性能更优,占用的存储空间少。所以,选择何种存储引擎,视具体应用而定。
再说一下不同引擎的优化,myisam读的效果好,写的效率差,这和它数据存储格式,索引的指针和锁的策略有关的,它的数据是顺序存储的(innodb数据存储方式是聚簇索引),他的索引btree上的节点是一个指向数据物理位置的指针,所以查找起来很快,(innodb索引节点存的则是数据的主键,所以需要根据主键二次查找);myisam锁是表锁,只有读读之间是并发的,写写之间和读写之间(读和插入之间是可以并发的,去设置concurrent_insert参数,定期执行表优化操作,更新操作就没有办法了)是串行的,所以写起来慢,并且默认的写优先级比读优先级高,高到写操作来了后,可以马上插入到读操作前面去,如果批量写,会导致读请求饿死,所以要设置读写优先级或设置多少写操作后执行读操作的策略;myisam不要使用查询时间太长的sql,如果策略使用不当,也会导致写饿死,所以尽量去拆分查询效率低的sql。
innodb一般都是行锁,这个一般指的是sql用到索引的时候,行锁是加在索引上的,不是加在数据记录上的,如果sql没有用到索引,仍然会锁定表,mysql的读写之间是可以并发的,普通的select是不需要锁的,当查询的记录遇到锁时,用的是一致性的非锁定快照读,也就是根据数据库隔离级别策略,会去读被锁定行的快照,其它更新或加锁读语句用的是当前读,读取原始行;因为普通读与写不冲突,所以innodb不会出现读写饿死的情况,又因为在使用索引的时候用的是行锁,锁的粒度小,竞争相同锁的情况就少,就增加了并发处理,所以并发读写的效率还是很优秀的,问题在于索引查询后的根据主键的二次查找导致效率低;
ps:很奇怪,为什innodb的索引叶子节点存的是主键而不是像mysism一样存数据的物理地址指针吗?如果存的是物理地址指针不就不需要二次查找了吗,这也是我开始的疑惑,根据mysism和innodb数据存储方式的差异去想,你就会明白了,我就不费口舌了!所以innodb为了避免二次查找可以使用索引覆盖技术,无法使用索引覆盖的,再延伸一下就是基于索引覆盖实现延迟关联;不知道什么是索引覆盖的,建议你无论如何都要弄清楚它是怎么回事!尽你所能去优化你的sql吧!说它成本低,却又是一项费时费力的活,需要在技术与业务都熟悉的情况下,用心去优化才能做到最优,优化后的效果也是立竿见影的!
设计
一、设计大表切入点
- 十个切入点
1 | 数据的容量 | 1-3年内会大概多少条数据,每条数据大概多少字节 |
2 | 数据项 | 是否有大字段,那些字段的值是否经常被更新 |
3 | 数据查询SQL条件 | 哪些数据项的列名称经常出现在WHERE、GROUP BY、ORDER BY子句中等 |
4 | 数据更新类SQL条件 | 有多少列经常出现UPDATE或DELETE 的WHERE子句中 |
5 | SQL量的统计比 | 如:SELECT:UPDATE+DELETE:INSERT=多少? |
6 | 执行量数量级 | 预计大表及相关联的SQL,每天总的执行量在何数量级? |
7 | 表中的数据 | 更新为主的业务 还是 查询为主的业务 |
8 | 什么架构 | 打算采用什么数据库物理服务器,以及数据库服务器架构? |
9 | 并发如何 | 采用怎么的处理并发的策略 |
10 | 存储引擎 | 存储引擎选择InnoDB还是MyISAM? |
- 多利用内存
至于优化若是指创建好的表,不能变动表结构的话,那建议InnoDB引擎,多利用点内存,减轻磁盘IO负载,因为IO往往是数据库服务器的瓶颈。
- 索引好,则优化SQL
另外对优化索引结构去解决性能问题的话,建议优先考虑修改类SQL语句,使他们更快些,不得已只靠索引组织结构的方式,当然此话前提是,
索引已经创建的非常好,若是读为主,可以考虑打开query_cache, 以及调整一些参数值:sort_buffer_size, read_buffer_size, read_rnd_buffer_size, join_buffer_size
二、实战
- 故事背景
- 策略效果
下面是一些相关测试和对比
(1) 首先看engine,在大数据量情况下,在没有做分区的情况下
mysiam比innodb在只读的情况下,效率要高13%左右
(2) 在做了partition之后,你可以去读一下mysql的官方文档,其实对于partition,专门是对myisam做的优化;对于innodb,所有的数据是存在ibdata里面的,所以即使你可以看到schema变了,其实没有本质的变化
在分区出于同一个physical disk下面的情况下,提升大概只有1%
在分区在不同的physical disk下,我分到了三个不同的disks下,提升大概在3%,其实所谓的吞吐量,由很多因素决定的,比如你的explain parition时候可以看到,record在那一个分区,如果每个分区都有,其实本质上没有解决读的问题,这样只会提升写的效率。
另外一个问题在于,分区,你怎么分,如果一张表,有三个column都是经常被用于做查询条件的,其实是一件很悲惨的事情,因为你没有办法对所有的sql做针对性的分区,如果你只是如mysql官方文档上说的,只对时间做一个分区,而且你也只用时间查询的话,恭喜你
(3) 表主要用来读还是写,其实这个问题是不充分的,应该这样问,你在写入的时候,同时并发的查询多么?我的问题还比较简单,因为mongodb的shredding支持不能,在crush之后,还是回到mysql,所以在通常情况下,9am-9pm,写入的情况很多,这个时候我会做一个view,view是基于最近被插入或者经常被查询的,通过做view来分离读取,就是说写是在table上的,读在进行逻辑判断前是在view上操作的
(4) 做一些archive table,比如先对这些大表做很多已有的统计分析,然后通过已有的分析+增量来解决
(5) 如果你用mysiam,还有一个问题你要注意,如果你的.configure的时候,加了一个max index length参数的时候,当你的record数大于制定长度的时候,这个index会被disable
[MySQL] 02- Optimisation solutions的更多相关文章
- 深入学习MySQL 02 日志系统:bin log,redo log,undo log
上一篇文章中,我们了解了一条查询语句的执行过程,按理说这篇应该讲一条更新语句的执行过程,但这个过程比较复杂,涉及到了好几个日志与事物,所以先梳理一下3个重要的日志,bin log(归档日志).redo ...
- day45 Pyhton 数据库Mysql 02
一.前期回顾 数据库 mysql的安装 配置环境 为什么要用数据库? 稳定性 一致性 并发 存取数据效率高 数据库的分类 关系型数据库 mysql oracle sqlserver 非关系型数据库 r ...
- mysql 02
CREATE TABLE emp(eid INT,ename VARCHAR(20),egender CHAR(2),ebirthday DATE,eemail CHAR(10),eramark VA ...
- RPM方式安装MySQL5.6和windows下安装mysql解压版
下载地址: http://cdn.MySQL.com/archives/mysql-5.6/MySQL-server-5.6.13-1.el6.x86_64.rpmhttp://cdn.mysql.c ...
- MySQL安装常见问题(找不到文件,系统服务无法启动...)
在安装mysql时总是会遇到问题,每次重新安装都会花很多时间来排查.在网上其实有很多相关的文章,但很多都只讲了方法,但没讲具体细节问题,导致无法解决问题.其实有时候知道问题的原因,但总是因为一些细节问 ...
- MySQL的left join中on与where的区别
关于 “A LEFT JOIN B ON 条件表达式” 的一点提醒 ON 条件(“A LEFT JOIN B ON 条件表达式”中的ON)用来决定如何从 B 表中检索数据行,即使on中包含有A表中的列 ...
- [转载] mysql5.6 删除之前的ibdata1文件后再重新生成,遇到[Warning] Info table is not ready to be used. Table 'mysql.slave_master_info' cannot be opened.问题
[转载] mysql5.6 删除之前的ibdata1文件后再重新生成,遇到[Warning] Info table is not ready to be used. Table 'mysql.slav ...
- 与MySQL交互(felixge/node-mysql)
目录 简介和安装 测试MySQL 认识一下Connection Options MYSQL CURD 插入 更新 查询 删除 Nodejs 调用带out参数的存储过程,并得到out参数返回值 结束数据 ...
- MySQL Windows 安装与配置
<01> 下载解压 MySQL 至 D盘, 将文件夹改名为 MySQL <02> 控制台状态下进入 MySQL/bin 目录 输入 mysqld -install 回车 安装 ...
- 修改MySQL命令提示符
当前session可以直接用prompt修改 mysql> prompt \u@\h \d \r:\m:\s>PROMPT set to '\u@\h \d \r:\m:\s>'ro ...
随机推荐
- Code signing is required for product type 'Unit Test Bundle' in SDK 'iOS 11.0.1'
Code signing is required for product type 'Unit Test Bundle' in SDK 'iOS 11.0.1' 进入 projects and lis ...
- MySQL基础(用的贼鸡儿多)
整理有点乱,业余也玩玩系统,经常碰见这些玩意,有点烦,老是记不住 MySQL 基础语法 一.连接 MYSQL格式: mysql -h 主机地址 -u 用户名 -p 用户密码. 1.连接到本机上的 MY ...
- Cassandra查询操作趟坑记录
例子表 CREATE TABLE employee ( name TEXT, age SMALLINT, phone TEXT, bornDate DATE, createDate timestamp ...
- CodeForces 909E
题意略. 思路:一个拓扑排序的题目吧.肯定是要先处理后面那个任务,再处理前面那个任务,我的思路是尽力先把主处理器能操作的先操作完,然后再把副处理器能操作完的再操作完,这样循环,直到处理完全部. 定义t ...
- Leetcode之二分法专题-367. 有效的完全平方数(Valid Perfect Square)
Leetcode之二分法专题-367. 有效的完全平方数(Valid Perfect Square) 给定一个正整数 num,编写一个函数,如果 num 是一个完全平方数,则返回 True,否则返回 ...
- Unity Shader 卡通渲染 基于退化四边形的实时描边
从csdn转移过来,顺便把写过的文章改写一下转过来. 一.边缘检测算法 3D模型描边有两种方式,一种是基于图像,即在所有3D模型渲染完成一张图片后,对这张图片进行边缘检测,最后得出描边效果.一种是基于 ...
- Delphi - Indy 创建邮件自动发送服务
服务器自动邮件线程 功能:此程序主要实现对Oracle数据库表tableName(存放需要发送邮件的相关信息)里面相关信息的邮件发送. 优点:开发人员可以直接再数据库后台对tableName表进行插入 ...
- hdu-6579 Operation
题目链接 Operation Problem Description There is an integer sequence a of length n and there are two kind ...
- POJ-1222EXTENDED LIGHTS OUT-位运算枚举模板
传送门:http://poj.org/problem?id=1222 题意:开关灯问题,一幅开关的灯中,给出一种操作,使得灯全关掉,(操作一个开关,相邻的灯也会改变) 思路:利用位运算枚举第一行: # ...
- codeforces 872 D. Something with XOR Queries(思维)
题目链接:http://codeforces.com/contest/872/problem/D 题意:给你一个排列p和对应的位置b也就是说p[b[i]]=i,然后给你最多询问2*n次找出所有的p排列 ...