性能监控工具
- sysbench
- pt-query-digest
- Anemometer
- new rilic
- xhprof生产环境下的PHP性能跟踪工具
- show profile
- show status
选择正确的数据类型
- 通常越小越好
- 越简单越好
- 采用not null
- 使用枚举类型
- TIMESTAMP通常优于DATETIME
- 多表关联,关联主键数据类型应当一致
- 不要怕用NULL,避免不存在的值,如:DATETIME NOT NULL DEFAULT ‘0000-00-00 00:00:00’
- 在冗余量允许的情况下,减少JOIN,考虑适当把同一个字段数据存到不同表里,使用触发器来维护,这可以减少全表扫描。
建立合适的索引
- 避免随机I/O
- 索引的选择性
- 对于联合索引,mysql只能高效利用最左前的字段,所以索引字段顺序很重要,
- B-Tree结构的索引,是按顺序存储索引key和数据指针的,如果索引key字符数较多,这会使索引很大。
- 可以对索引数据进行hash,用数据的hash来索引数据。使用触发器进行维护。
- “独立的列”,应当把索引单独放在比较符号的一侧,mysql才能利用其索引来。
- 前缀索引,对于长字段,可以只索引字段前缀部分,如host(10)
- Innodb使用的聚簇索引,按主键顺序连续存储数据和索引。
- 覆盖索引,索引本身含有查询所需的全部数据。
- MyISAM按插入顺序存储数据,每行定长,这在查询的时候可以直接跳过
- Mysql5.6可以推送索引条件到存储引擎层
- 冗余索引,对于(A,B)来说要查询B,(A)是冗余索引,(B),(B,A)则不是
- 对于mysql查询,mysql可以利用第一个范围查询之前所有列的最左前索引
- 技巧,使用闭合条件来优化查询,如:有一个索引INDEX(‘sex’,‘country’,‘age’),如何我们要查询所中国26岁的用户,country并不是最左前字段,利用不了这个索引,我们可以用闭合条件,SEX IN(‘男’,‘女’),跳过sex字段,使用这个索引。
- 延迟关联,在查询一个大列表的冷数据时,可能会使用limit 1000000,10 这样的,这对Mysql来说,他需要扫描并丢弃前1000000行。我们可以先只查询出主键id,再根据主键id查询对应数据,可以减少系统传输的数据量,减少I/O开销
- 避免单行查找,即使是单行查找,系统也会有很多准备工作。
查询优化
- mysql的处理流程是,先取一个大的结果集,慢慢丢弃不需要的结果。理解这个流程,可以预想到一个SQL,mysql会怎样处理。
- 联表查询会返回全部列
- 分解关联查询,可以提高缓存命中率,减少锁,提高程序拓展性。
- 避免IN()一个结果集,如where a.id IN(select id from…),改成inner join
- 没有万能经验,子查询和join性能可以多实测
- mysql通过嵌套循环来实现查询,即使是一条简单select
- 大数据量的limit优化,其实对于多数应用,列表数据是允许少量冗余的,可以考虑传入上一页的最后一个主键id作为定位条件,不用limit准确的偏移。
Mysql高级特性