mysql 优化 (1)

提高IOPS能力的几种方法
换SSD,PCIE-SSD(提高IO效率,普通SAS盘5000以内的iops,而新设备可达到数万或者数十万iops)
少做IO的活(合并多次读写为一次,或者前端加内存CACHE;或者优化业务,消除IO)
加大内存(更多hot data和dirty data放在内存中,减少物理IO)
调整文件系统为xfs(相比ext3、ext4提高IOPS能力,高io负载下表现更佳)
调整raid级别为raid 1+0(相比raid1、raid5等提高IOPS能力)
调整写cache策略为wb或force wb(利用阵列卡cache,提高iops)
io scheduler(优先使用deadline,如果是SSD,则使用noop)

SSD设备相关优化手段
• 通过调整 /sys/block/sdx/queue/read_ahead_kb 观察到预读大小为16KB(具体多少要看平均每次IO读大小),通过适当预读提高整体性能。
• 大量的IO请求数必定会产生庞大数量的中断请求,因此需要在多核上绑定中断,避免单核负载过高。

vm.swappiness 设置为0表示尽量少swap,100表示尽量将inactive的内存页交换出去,在内存不够用时,释放掉,尽量不使用swap
RHEL 7以下设置为0,RHEL 7以上谨慎设置为5 ~ 10,减少使用swap的概率
[root@localhost ~]# cat /etc/sysctl.conf |grep vm.swappiness
[root@mysql1 ~]# vim /etc/sysctl.conf
[root@mysql1 ~]# sysctl -p
mysql 不使用HugePages
### TokuDB need this kernel settings, start
echo never &get; /sys/kernel/mm/redhat_transparent_hugepage/defrag
echo never &get; /sys/kernel/mm/redhat_transparent_hugepage/enabled
echo never &get; /sys/kernel/mm/transparent_hugepage/enabled
echo never &get; /sys/kernel/mm/transparent_hugepage/defrag
### TokuDB need this kernel settings, end

deadline: deadline 算法保证对既定的IO请求以最小的延迟时间。
anticipatory: 有个IO发生后,如果又有进程请求IO,则产生一个默认6ms猜测时间,猜测下一个进程请求IO是干什么。这对于随机读取会造成较大的延时。对数据库应用很糟糕,而对于Web Server等则会表现不错。
cfq: 对每个进程维护一个IO队列,各个进程发来的IO请求会被cfq以轮循方式处理,对每一个IO请求都是公平。适合离散读的应用。
noop: 对所有IO请求都用FIFO队列形式处理。默认IO不会存在性能问题。

首选xfs,其次ext4
mount参数:noatime, nodiratime, nobarrier
对于ext3, ext4和 reiserfs文件系统可以在mount时指定barrier=0;对于xfs可以指定nobarrier选项

query_cache_type = 0
query_cache_size = 0
tmp_table_size / max_heap_table_size 不建议超过128MB,高并发,简单SQL的场景中,不建议超过64MB
sort_buffer_size / read_buffer_size 等不建议超过8MB
纯InnoDB环境下,key_buffer_size 不建议超过32MB

日志相关
long_query_time = 0.01(10毫秒)
pt-query-digest + Box Anemometer,构建slow query log分析系统
genral_log = 0
log_warnings = 2
binlog = 0/1
sync_binlog = 0/1/N 需要权衡
log_slave_updates = 0/1,在一个集群中,只有一个SLAVE节点开启,其他SLAVE都不开启

MySQL Schema设计原则、优化建议
• 默认InnoDB,杜绝MyISAM
• 不对InnnoDB表进行在线实时统计
• InnoDB表显式指定自增INT型为主键
• 表字段设计:简单至上
• INT/TIMESTAMP记录时间,而非DATETIME
• IPV4地址用INT,而不是CHAR(15)
• 性别采用ENUM(1,2,3)或者是 tinyint,而不是INT,甚至CHAR
• 杜绝TEXT、BLOG,确实需要则拆分
• 存储较长字符串内容时,提前进行(物理、逻辑)压缩、序列化(JSON/BSON格式)
• 相同用途未来可能会作为JOIN依据的字段,在各个表里的定义属性完全一致
• 显式约束:NOT NULL,DEFAULT ''

CREATE TABLE `sy_hot_words` (
`id` int(11) NOT NULL,
`hot_words` varchar(510) default NULL COMMENT '热词以逗号隔开',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
可以调整为纵向存储,或使用其他模糊搜索技术实现,
或者拆分开,采用 1对N 的结构实现,或者在nosql里,用K-V方式存储

Schema设计、优化,我们可做的
-- 理解各业务产生的数据流,以及读写数据的方式;
-- 整理数据流中的每个数据项属性信息(类型、范围、过滤性);
-- 分析业务指标,推测数据规模(需要考虑相对长远,例如半年以上,也可以生成一定量级的测试数据,例如至少100万行);
-- 选择相对最适用的硬件设备和数据库架构;
-- 权衡各个SQL的性能和IO量,也即类似于哪个操作权重高一些,那些操作权重适当低一些;
-- 创建适当的索引;
-- 收集测试和生产环境的反馈信息,持续优化索引及表设计;

索引使用中的局限性
- 通过索引扫描的记录数超过30%,变成全表扫描
- 联合索引中,第一个索引列使用范围查询
- 联合索引中,第一个查询条件不是最左索引列
- 模糊查询条件列最左以通配符 % 开始
- 内存表(HEAP 表)使用HASH索引时,使用范围检索或者ORDER BY
- 两个独立索引,其中一个用于检索,一个用于排序

• 主键/唯一索性能引优于普通索引
• 复合索引比普通索引更合适
• 过度索引可能会带来灾难,够用就行
• 基数(cardinality)很小的列上不建索引
• 长字段使用部分索引,而非全部
• 冗余反向字段便于反向检索
• 采用第三方全文索引工具或者关键字(TAG)对TEXT/BLOB/CHAR字段检索
• 常用检索、排序字段,需要创建索引
• 常用检索、分组(GROUP BY)、排序(ORDER BY)字段,需要创建索引

原文地址:https://www.cnblogs.com/yhq1314/p/10671195.html