## 基础常识 ##
一般应用系统,读写比例在10:1左右
磁盘IO的时间成本是内存的十万倍左右
关于索引:高可用多路搜索树B+Tree结构。非叶子节点不存储真实的数据,只存储指引搜索方向的数据项。
*******************************************************************************************************
##################################### 数据库各阶段的调优 #####################################
**********************************************************************************************
表引擎选择
频繁插入更新的表使用InnoDB引擎, 主要读取的表使用MyISAM引擎
字段设计
尽可能小的字段类型,NOT NULL(避免NULL比较),约束默认值(减少插入次数),ENUM代替String类型(ENUM被当做数值类型处理)
合理设计索引
## 索引建立原则 ##
优先使用UNIQ索引,NOT NULL,长度尽量短
选择区分度高的where、order列创建索引(区分度小于0.3查询计划会忽略索引,唯一键的区分度是1)
尽量的扩展复合索引,不要新建索引
范围查询>、<、between、like列放在复合索引的最后(因为索引查询遵循最左前缀匹配原则,查询时会按复合索引的列顺序一直向右匹配直到遇到范围查询就停止)
## 索引使用原则 ##
where的列顺序不做要求,查询计划会自动调整以匹配复合索引列顺序
批量数据插入前应禁用索引,结束后再更新索引
适当添加冗余字段
合理设计的字段冗余能减少多表查询,提高查询效率,空间换时间
简化权限设置
简化的权限能加快每次查询时的权限判断
不要在FROM之前使用子查询, 改为Join代替子查询
这种情况会针对主表的每条记录进行一次子查询,大量生成生成临时表,占用内存资源。
不好的使用示例: select a.*, (select name from bb where bb.boos_id = a.id) as b from a where a.age between 30 and 40
可以考虑在FROM之后做子查询, 生成记录数较少的子表, 小表驱动后续的大表查询
有时候子查询出一张小表,从而将驱动表规模缩减,然后进行后续查询能显著提高效率。
这里虽然进行了子查询但是仅生成了一次临时表,且极大的缩减了驱动表规模,如果最终缩减的规模良好,则可以采用此方案优化。
良好的使用示例:select a.* from (select * from aa where age between 30 and 40) as a left join caiwu on caiwu.boos_id = a.id;
字段比较使用相同数据类型
避免比较时发生类型转换,类型转换可能还会导致索引无效
使用持久化连接
避免反复创建连接带来的性能损耗
启用慢查日志
慢查日志能记录项目运行过程中的慢查语句,留待进一步分析
Explain分析慢查语句
设置SQL_NO_CACHE,explain分析语句,查看执行计划
若有排序表,则排序的表优先查。否则分析where条件单表,从锁定记录较少的表开始查询
查询序列号越大, 优先级越高,越先被执行
留意执行计划中索引的使用情况
需要强调rows是核心指标,扫描行数少的语句执行一定快
show profile分析
对sql语句做性能分析,查找效率瓶颈
复制特性
利用该特性做主从, 实现读写分离
分库分表
利用月分表等类似的水平分表方案直接减小单表记录规模,提升查询效率
利用切分不常用表字段等类似的垂直分表方案减小单表体量,提升查询效率
参数调优
连接负载back_log,最大并发连接数max_userd_connection
OPTIMIZE语句
通过表优化语句,做空间回收,数据重排,更新统计等工作