高效MySQL的N个习惯

用更好的硬件

用更好的CPU

  • 主频高,让每个SQL处理时间更快,减少等待
  • L1/L2/L3 Cache更大,每次CPU计算速率更快
  • 线程多,同时支持更多并发SQL,提高TPS同时关闭NUMA并设置为最大性能模式

注:TPS的意思是系统吞吐量,关于相关概念的理解,我这里转载了一篇不错的文章可以给大家借鉴参考一下。

用更好的内存

  • 主频高,内存读写速率更高,更高吞吐,更低时延
  • 内存大,更多数据在内存中,减少直接磁盘读写,提高TPS

用更好的磁盘

  • 通常来说,磁盘I/O是最大的瓶颈
  • 如果是机械硬盘一定要配阵列卡,以及阵列卡的CACHE&BBU,并且使用(FORCE)WB策略
  • 最好选用SSD或者PCle SSD, iops可以提升成千上万倍

用更好的网卡/网络

  • 文件传输速率高,异地文件备份更快
  • 主从数据复制数据传输时延更小
  • 适合大数据量的分布式存储环境
  • 老版本内核中,网络请求太高时会引发中断瓶颈,建议升级内核
  • 多个网卡可以进行绑定,提高传输速率并提高可用性

让OS跑得更快

关闭无用服务

  • 减少系统开销
  • 避免潜在安全隐患

尽可能使用本地高速存储

  • 坚决不用nfs
  • 除非是基于SSD的高速网络分布式存储
  • 用于备份场景除外

让数据库跑在专用服务器上,不混搭

  • 性能上不相互影响
  • 提高安全性
  • 必须混搭时要做好权限管理以及安全隔离

io scheduler

  • 选择deadline, noop,坚决不用cfq

注:CFQ,即Completely Fair Queueing绝对公平调度器,力图为竞争块设备使用权的所有进程分配一个等同的时间片,在调度器分配给进程的时间片内,进程可以将其读写请求发送给底层块设备,当进程的时间片消耗完,进程的请求队列将被挂起,等待调度。相对于Noop和Deadline调度器,CFQ要复杂得多,因此可能要分几次才能将其分析完。

文件系统选择

  • 优先选用xfs或ext4(rhel 7及以上,xfs已是默认fs)
  • zfs/btrfs比较小众
  • 坚决不用ext3

其他内核选项

  • vm.dirty_ratio<=5
  • vm.dirty_background_ratio<=10
  • 避免因为io压力瞬间飙升导致内核进程卡死,os挂起

DDL,SQL写得好

(接下来就跟数据库有很大关系了,就看各位平时的数据库经验了)

一定要有主键(PRIMARY KEY)

如果没有主键的话,数据多次读写后可能更加离散,有更多随机IO。在MySql赋值环境中,如果选RBR模式,没有主键的update需要读全表,导致赋值延迟。好主键有以下特点:

  • 没有业务用途
  • 数值呈连续增长,最好是自增
  • 坚决不能选用CHAR/UUID等类型

以上这些标注了红色的地方表示我还没有理解的,哪位朋友看了可以跟我解释一下。

关于数据长度

  • 在够用的前提下,越短越好
  • 消耗更少的储存空间
  • 需要进行排序时候,消耗更少的内存空间
  • 例如用INT UNSIGNED存储IPV4地址,不用CHAR(15)类型
  • 实例:11个字符长度的数值,bigint vs char(11) vs char(11), 1w条记录,Logical_read: 111 vs 1170 vs 224

适当使用TEXT/BLOB类型

  • data page默认16kb
  • 每行长度超过8kb时候,就需要分裂data page
  • 产生更多离散IO
  • 案例:一个100G的表拆分成4个表后,总大小仅25G

每个表增加create_time update_time两个字段

  • 分别表示写入时间以及最后更新时间
  • 业务上可能用不到,但是对日常运维管理非常有用
  • 可以用来判断那些事可以归档的老数据,定期进行归档
  • 用来做自定义的差异备份也很方便

索引很重要

  • InnoDB行锁基本是基于索引的实现
  • 如果没有索引,后果将是灾难性的,读取时全表扫描,修改时全表记录锁。

索引设计

  • 基数低的字段没必要建立单列索引
  • 字符型字段上建立索引时候优先采用部分索引
  • 优先多列联合索引,少用单列索引

什么是好的SQL

  • 所有WHERE条件都加引号
  • 避免潜在的隐士转换风险
  • 避免个别条件失效时候的SQL语法错误
  • 不用SELECT *
  • 减少不必要的IO
  • 提高可以利用覆盖索引的几率
  • 避免SQL注入风险
  • 所有用户输入值都要做过滤
  • 利用PREPARE做预处理
  • 利用SQL_MODE做限制
  • LIKE查询时候不要用%通配符最左前导(无法使用索引)
  • 能UNION ALL的时候就不要用UNION,因为UNION需要去重复,会产生临时表
  • SQL中最好不要有预算
  • WHERE子句中不要有函数

关于JOIN

  • 满足业务需求前提下尽量用inner join,让优化器自动选择驱动表
  • 有时候优化器选择的驱动表未必是最优的,可以尝试手动调整
  • 最后的排序字段如果不在驱动表中,则会有filesort

关于EXPLAIN

  • 关键业务SQL上线前,都要EXPLAIN确认其执行计划
  • 或提前分析slow query log,防患于未然
  • EXPLAIN中如果有Using temporary Using filesort 或 type=ALL时候,尽量想办法优化

运维习惯好

存储引擎

  • 抛弃MyISAM, 拥抱InnoDB(这篇文章讲述了二者区别)
  • 适当场景下可以使用TokuDB
  • MEMORY不一定快

关闭QUERY CACHE

  • 绝大多数情况下鸡肋,最好关闭
  • QC锁是全局锁,每次更新QC的内存块锁代价高,出现wating for cache lock状态频率很高
  • 实例启动前设置query_cache_type = 0 & query_cache_size =0 –
  • 参考:http://t.cn/RAF4d7z http://t.cn/RAF4d7Z

使用独立undo表空间

  • 避免ibdata1文件存储空间暴涨
  • MySQL 5.6开始支持独立表空间
  • MySQL 5.7还可以回收已经purge的表空间
  • 提高file i/o能力,并适当增加purge线程数 innodb_purge_threads
  • 事务及时提交,不要积压。并且默认打开autocommit = 1

启用thread pool

  • 应对突发短连接
  • extra port 

没thread pool怎么办

  • 想办法启用连接池或其他替代方案
  • 适当调低超时阈值,减少空闲连接

几个关键选项

  • innodb_buffer_pool_size,约物理内存的50% ~ 70%
  • innodb_log_file_size,5.5及以上2G+,5.5以下建议不超512M
  • innodb_flush_log_at_trx_commit,0=>最快数据最不安全,1=>最慢 最安全,2=>折中
  • innodb_max_dirty_pages_pct,25%~50%为宜
  • max_connections,突发最大连接数的80%为宜,过大容易导致全 部卡死

启用辅助监控机制

  • 干掉超过N秒的SQL
  • 干掉疑似注入SQL
  • 干掉长时间不活跃的sleep连接

其他好习惯

DML(data manipulation language)是数据操纵语言:它们是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言。

DDL(data definition language)是数据定义语言:DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定义或改变表(TABLE)的结构,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用。
DCL(DataControlLanguage)是数据库控制语言:是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。

 online ddl

  • 优先用pt-osc
  • 但不见得一定要用pt-osc
  • 尤其是5.6以后对online ddl有了很大提升改善

删除大表

  • 不要真的删除,而是先rename
  • 确认对业务真的没有影响
  • 再用硬连接的方法物理删除,效率更高

autocommit

  • 避免某些行锁被长时间持有,影响tps
  • 更严重时,可能连接数暴涨,导致整个实例挂掉
  • 采用gui客户端连接时,记得及时关闭连接,或设置超时阈值以及 自动提交,否则容易发生行锁等待问题

转载于:https://my.oschina.net/hunglish/blog/864853

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值