Mysql 阶段调优

效率基础

  • 通常应用读写比例大概在10:1
  • IO成本磁盘大概是内存的十万倍
  • 高负载读应用支持千万量级数据,高负载写应用支持百万量级数据
  • 索引采用了高可用多路搜索树构(B+Tree,非叶子节点不存储真实的数据,只存储指引搜索方向的数据项)
  • 索引查询遵循最左前缀匹配原则

数据库阶段调优

1. 数据设计阶段

  • 表引擎选择
    高频插入、更新的表使用InnoDB引擎
    高频读取的表使用MyISAM引擎mysql

  • 字段设计
    字段名:所有小写、下划线链接
    尽量小的字段类型 ,尽量unsigned
    NOT NULL(避免NULL比较)
    字段约束默认值(减小插入次数)
    ENUM代替String类型(ENUM被当作数值类型处理,这条较少运用)
    小数使用decimal类型,长度不够则拆分整数和小数分别存储
    文本字段:长度接近则char,不一样则varchar,超过5000则text并建议单独表(不然影响其余数据索引效率)sql

  • 合理利用索引
    索引创建原则
    索引名:主键pk_前缀,惟一uk_前缀,普通idx_前缀
    UNIQ索引优先于INDEX索引 选择区分度高的whereorder列建立索引(区分度小于0.3查询计划会忽略索引,惟一键的区分度是1)
    尽可能的扩展复合索引,不要新建索引(区分度高的字段放最左边)
    范围查询><betweenlike列放在复合索引构建字段集的的末尾(复合索引查询向右匹配直至范围查询列而止)
    索引使用原则
    where的列顺序不作要求,查询计划会自动调整以匹配复合索引列顺序
    批量数据插入前应先删除索引,结束后再重建
    排序字段要利用索引, 只能结合过滤字段作复合索引数据库

  • 冗余字段
    适当添加的字段冗余能减小多表查询,提升查询效率
    空间换时间
    冗余字段不该该是超长字段、频繁更新字段(不然数据一致性的处理成本过高)缓存

  • 简化权限设置
    sql查询前的权限判断有较高的时间损耗swoole

2. 查询阶段

  • 小表驱动大表查询
    能够考虑在FROM以后利用子查询,尽量的在最终查询前缩减表规模 如:select x.* from (select * from a where id < 100) as x left join b on b.extid= x.id架构

  • 避免在FROM以前使用子查询
    应改成JOIN代替,不然主表每条记录都会进行一次子查询产生笛卡尔积问题,占用大量内存资源
    如:select a.*, (select x from y where extid = a.id) as b from a并发

  • 字段比较使用相同数据类型
    避免查询值和字段原始类型比较时发生类型转换,类型转换可能还会致使索引无效,同时引入巨大的转换开销运维

  • join查询
    join字段必须类型一致,且索引性能

  • like查询
    禁止左模糊或者全模糊(索引文件具备B-Tree的最左前缀匹配特性,若是左边的值未肯定,那么没法使用此索引)
    考虑使用检索引擎实现优化

3. SQL调优阶段

  • 慢查日志
    慢查日志能记录应用运行期间超出时间阈值的慢查询

  • Show Profile分析
    sql语句性能分析,查找效率瓶颈

  • Explain分析查询计划

**使用**
    - `explain 查询语句`
    - 查询序列号越大, 优先级越高,越先被执行  
    
    **几个重要字段**
    - select 当前的查询类型:简单查询、联合查询等
    - possible_keys 当前查询的可选索引
    - key 当前查询实际使用索引

    **优化目标(通常经过索引来达成)**
    - 优化访问类型type(优到次顺序为:·system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>ALL·)
    - 显示覆盖索引 using index
    - 减小扫面行数rows
    - 避免Using filesort

4. 链接优化阶段

  • 链接参数调优
    最大并发链接数max_connectionsmax_user_connections
    最大请求暂存堆栈数back_log

  • mysql线程缓存池复用链接
    配置thread_cache_size参数(每G内存能够配备8个链接线程,但要小于数据库链接数限制)

  • mysql长链接在超时内复用链接

  • 中间件维护链接池复用链接
    可经过swoole来实现链接池

5. 架构优化阶段

  • 设计冗余中间表
    将高耗时的子查询结果集装载到一张冗余中间表中

  • 复制特性作主从
    读写分离
    自动故障切换避免单点问题

  • 垂直分库分表
    大表拆小表,不经常使用字段移植到新建表中,减少单表规模
    为了后期的水平拓展优化,这里要求禁用 join查询、子查询等

  • 水平拓展策略 - 分库分表
    单表超过500万行或2G才建议分库分表
    该措施会在后期形成较多的开发、运维困难,不到万不得已不建议实施
    利用 MOD、HASH、月分表 等shard方案减少单表规模

  • 应用/数据库之间架设缓存层 尽可能避免请求直接穿透到数据库

6. 平常维护阶段

  • OPTIMIZE语句
    空间回收、数据重排、更新统计等工做

  • 设备升级 使用RAID、SSD等高速IO设备 切换到云数据库


其中,水平分库分表、读写分离、链接池等措施通常都要借助于数据库中间件来实施。

相关文章
相关标签/搜索