- 1表越窄越好
- 2表越小越好
- 3请求够高效
1表越窄越好
设计表字段的时候,选择的数据类型足够用就好
show table status查看表的统计信息Avg_row_length值超过100字节需要注意并优化
2表越小越好
好的架构要配合业务的需求用尽可能小的数据量或者让线上的业务表它的数据量尽可能小,尽可能让线上生产环境里面的这些热表(经常使用的表足够小减少IO操作代价)
解决方案:分库分表、冷热数据分离
判断手段:
行数尽可能不要超过5000万行
宽表<=50万
3请求要足够高效
每条SQL尽快完成,让每个事物尽快提交/回滚
理由:
修改、删除数据 会锁定数据行,如果行被锁定或者它可能会产生对应的一些表锁,锁资源如果没有释放的话会导致其他SQL或事务被阻塞
解决方案:
监控mysql的线程状态
监控innodb的事务状态
来确认那些运行时间特别持久的SQL,或者是长时间没有提交的事务
超过5秒没有执行的sql或事务要发出告警
或者设置修改/锁定行数的阈值>10行 告警
检查或者监控sql注入的风险(sleep()函数、union all()请求)
一、schema设计原则
1 尽量小的原则
2 为了高并发,禁止使用外键(外键会增加行所导致锁的阻塞和等待时间)
如果为了保证数据的一致性,在业务层修改就好
3 自增int、bigint主键(innodb引擎,数据按照具体索引的顺序来进行存储)使用其他类型(char uuid)做主键 数据存储的顺序离散随机造成磁盘空间的浪费而且还会影响性能
4字符集和库表的设计要一致
(mysql实例–database–》数据库表–字段–》存储过程–event 都保持一致)
utf8:3字节
utf8mb4:4字节
当字符集不同的两个表join时 会造成数据类型的隐式转换导致索引会失效
5mysql高效的建议
单表
- 单表的数据量尽量不要超过5000万
- 单表的物理大小不要超过20个G
- 索引的数量不要超过5个
总的大小不要超过500g
总表的数量不超过5000个
二 库表字段设计规范
- 每个表建议不超过50个字段
- 优先选择utf8mb4字符集(它的兼容性最好,存储表情)
- 严禁在数据库中使用明文存储用户的一些核心数据(身份证、信用卡号)
- 用好int数据类型 int效率高float效率低
- 遇到blob text 字段 尽量拆出去,再用主键关联(blob、text这种大对象数据类型除了会造成宽表外还会发生行溢出这样的风险,也会造成更高概率的存储碎片)
- 字符类型尽可能使用varchar的数量类型(varchar更灵活可以存储的可变范围更大一些,存储更高效)
- 日期时间数据建议采用datetime类型 (可存储的时间比timestamp范围大)
sql开发
- 多表join时,join列的数据类型要一致(索引失效)
- 多表join时,把where条件过滤后结果集较小的表作为驱动表(EXPLAN执行计划分析)
- 在查询的where条件中用上函数或表达式要8.0版本(支持表达式索引倒叙索引等)
- 不要看见where条件中出现的列就直接创建索引
通过 general log 或 long_query_time=0看哪条SQL出现的频率高或者是SQL的代价更高,针对这些SQL进行有针对性的去创建合适的索引 - 尽可能不要执行select*操作
- 不要执行like “%x%”(全表扫描)
- 尽量不要使用“!=”条件 (肯能会出现全表扫描)
- 如果能确定返回结果数量的话最好加上limit n(优化器会自动优化 得到结果会停止继续扫描)
- 优先使用union all 代替union(mysql5.6之后减少临时表的生成)
10.所有SQL都要通过SQL审查系统检查符合标准后才能上线