MYSQL优化思路
数据库配置上分为索引设置和参数设置(主要是各个buffer size);另个方面在数据操作上,避触发MYSQL耗时、耗CPU操作
数据库设置
- 索引
- 覆盖索引:避免回表
order by
- 未加索引的情况,order by依据数据量会进行以下排序策略:
sort buffer
足够大: 全字段排序sort buffer
不太够: rowid排序+回表sort buffer
不够:临时文件归并排序
- 加索引的情况
- 索引未覆盖到所有选择列:回表
- 索引覆盖到所有选择列:无需回表,直接输出
- 未加索引的情况,order by依据数据量会进行以下排序策略:
group by
- 未加索引情况下,建立临时表,记录依次upsert插入临时表,最后默认再进行排序(如无需排序,建议:
group by f order by null
) - 加索引情况下,直接顺序累加,不再走
temporary
、file sort
- 未加索引情况下,建立临时表,记录依次upsert插入临时表,最后默认再进行排序(如无需排序,建议:
join
- 被驱动表上没索引,走BNL:
- 如果join buffer足够大能装得下被驱动表,扫描行N+M,判断次数N*M,无论大表还是小表作为驱动表效率一样
- 如果join buffer不够大不能装下被驱动表,扫描行N+(N/join_buffer_size+1)M,判断次数NM,由扫描行公示可知,被驱动表N越小,扫描次数越少
- 被动驱动表上有索引,走NLJ:
- 扫描的N条待匹配记录,每一条都根据索引树查找,复杂度是log2M,如果算上回表的话,那就是2log2M。所以整体时间复杂度是N+N2*log2M,N越小越好即被驱动表越小越好
- 被驱动表上没索引,走BNL:
buffer设置大小
数据页合并、数据页分裂
- 随机插入和删除,如uuid方式新增
- 锁
- 减少行冲突:死锁检测耗费cpu
- 将冲突高的sql或行放在事务后面执行:二阶段锁协议
- 避免大(长)事务
- 长期占用MDL读锁,导致DDL拿不到MDL写锁
- undolog不能回收,空间膨胀
- 主从延迟
- 高并发下,数据库连接池容易撑爆