MYSQL原则

一.核心军规(5)

1.尽量不在数据库做运算

①尽量不在数据库做运算 ②复杂运算移到程序端CPU ③尽可能简单应用MySQL

2.控制单表数据量

  ①一年内的单表数据量预估 ,纯INT不超过1000W,含CHAR不超过500W

  ②合理分表不超载   

    Ⅰ做mysql集群,例如:利用mysql cluster ,mysql proxy,mysql replication,drdb等等

    Ⅱ 可以根据月份、季度、年进行分表 --时间

    Ⅲ 主键id范围、取模 、哈希进行分表 

    Ⅳ Mysql的MyISAM存储引擎

  ③建议单库不超过300-400个表

3.保持表身段苗条

  ①表字段数少而精

  ②单表1G体积 500W行评估

    Ⅰ顺序读1G文件需N秒

    Ⅱ单行不超过200Byte

    Ⅲ单表不超50个纯INT字段

    Ⅳ单表不超20个CHAR(10)字段

  ③单表字段数上限控制在20~50个

4.平衡范式不冗余

  ①严格遵循三大范式

  ②效率优先、提升性能

  ③没有绝对的对不错

  ④适当时牺牲范式、加入冗余

  ⑤但会增加代码复杂度

     补充:

    第一范式(1NF)
                1NF是指数据库中表的每一列都是不可分割的基本数据项,同一列的数据不
                 能有多个值。如果出现重复,就可能需要定义一个新的实体(即:生成一
                 个新的表)来描述关系。
                 例如:公司中某个人员隶属于多个部门,那么在人员中,这个人部门字段
                 可以存储多个值,但是这样违反了1NF。
                 解决办法:此时可以生成一个新表,表示人员与部门的关系。

         第二范式(2NF)
                 2NF是在1NF的基础上建立的,所以满足2NF的必须满足1NF;
                 2NF要求数据库中表的每个实例或行必须能唯一的区分。为实现区分通常需要为表加上一个列(主键)或多列(联合主键);
                 2NF要求实体的属性完全依赖于主键。如果存在依赖主键一部分的属性
                 那么这个属性和主键应该分离出来形成一个新的实体,新实体于原实体之间
                 是一对多的关系。简而言之,就是2NF非主属性不能部分依赖于主键。

           第三范式(3NF)
                 3NF依赖于2NF;
                 3NF要求一个数据库表中不包含在其他表中已经存在的非主键的字段;
                 3NF表属性不能依赖其他表中非主键的属性;

5.拒绝3B(运行的时间比较长,操作的数据比较多)

  ①大SQL (BIG SQL)

  ②大事务 (BIG Transaction)

  ③大批量 (BIG Batch)

二.字段类军规(6)

1.用好数值字段类型

  三类数值类型: ①TINYINT(1Byte) 、 SMALLINT(2B) 、 MEDIUMINT(3B) 、 INT(4B)、BIGINT(8B)

          ②FLOAT(4B)、DOUBLE(8B)

          ③DECIMAL(M,D)

2.将字符转化为数字

  数字型VS字符串型索引 ① 更高效 ② 查询更快③ 占用空间更小

3.优先使用枚举ENUM/SET(ENUM类型只能从成员中选择一个,而SET类型可以选择多个。 ENUM和SET类型都是集合类型,不同的是ENUM类型最多可枚举65535个元素,而SET类型最多枚举64个元素。且set中可以存set枚举中的组合)

  ①优先使用ENUM或SET

    Ⅰ 字符串

    Ⅱ 可能值已知且有限 

  ②存储

    Ⅰ ENUM占用1字节,转为数值运算

    Ⅱ SET视节点定,最多占用8字节

    Ⅲ 比较时需要加‘ 单引号(即使是数值)

  ③举例

    Ⅰ `sex` enum('F','M') COMMENT '性别'

    Ⅱ `c1` enum('0','1','2','3') COMMENT '职介审核'

4.避免使用NULL字段

   ① 很难进行查询优化

  ② NULL列加索引,需要额外空间

  ③ 含NULL复合索引无效

5.少用幵拆分TEXT/BLOB

  ①TEXT类型处理性能远低亍VARCHAR

     强制生成硬盘临时表

     浪费更多空间

     VARCHAR(65535)==>64K (注意UTF-8)

  ②尽量不用TEXT/BLOB数据类型

  ③若必须使用则拆分到单独的表

6. 不在数据库里存图片

三.索引类军规(5)

1. 谨慎合理添加索引

  ①改善查询 、 减慢更新 、 索引不是越多越好

  ②能不加的索引尽量不加

  ③结合核心SQL优先考虑覆盖索引

2. 字符字段必须建前缀索引

 

3. 不在索引列做运算

  不在索引列进行数学运算或凼数运算 

  ①无法使用索引 ②导致全表扫描

4.自增列或全局ID做INNODB主键

  ① 对主键建立聚簇索引

  ② 二级索引存储主键值

  ③ 主键不应更新修改

  ④ 按自增顺序插入值

  ⑤ 忌用字符串做主键

  ⑥ 聚簇索引分裂

  ⑦ 推荐用独立亍业务的AUTO_INCREMENT列或全局ID生成 器做代理主键

  ⑧ 若不指定主键,InnoDB会用唯一且非空值索引代替

5. 尽量不用外键(建议由程序保证约束)

  ① 外键可节省开发量

  ② 有额外开销

  ③ 逐行操作

  ④ 可‘到达’其它表,意味着锁

  ⑤ 高幵发时容易死锁

四.SQL类军规(15)

1.SQL语句尽可能简单

  ①可能一条大SQL就把整个数据库堵死

  ②简单SQL缓存命中率更高, 减少锁表时间,特别是MyISAM ,用上多CPU

2. 保持事务(连接)短小

  ①. 事务/连接使用原则:即开即用,用完即关

  ②. 不事务无关操作放到事务外面, 减少锁资源的占用

  ③. 不破坏一致性前提下,使用多个短事务代替长事务

3. 尽可能避免使用SP/TRIG/FUNC(由客户端程序负责)

  ① 尽可能少用存储过程

  ② 尽可能少用触发器

  ③ 减用使用MySQL凼数对结果进行处理

4. 尽量不用 SELECT *

  ①用SELECT * 时

    Ⅰ更多消耗CPU、内存、IO、网络带宽

    Ⅱ 先向数据库请求所有列,然后丢掉不需要列

   ②尽量不用SELECT * ,叧取需要数据列 

    Ⅰ 更安全的设计:减少表变化带来的影响

    Ⅱ 为使用covering index提供可能性

    Ⅲ Select/JOIN减少硬盘临时表生成,特别是有TEXT/BLOB时

5. 改写OR语句(注意控制IN的个数,建议n小亍200,当n很大时,OR会慢很多 )

  • 同一字段,将or改写为in()

     ①OR效率:O(n) 

     ②IN 效率:O(Log n) 

  • 不同字段,将or改为union

    ①减少对不同字段进行 "or" 查询

    ② Merge index往往很弱智 , 如果有足够信心:set global optimizer_switch='index_merge=off';

6. 避免负向查询和% 前缀模糊查询

  ① 避免负向查询   NOT、!=、<>、!<、!>、NOT EXISTS、NOT IN、 NOT LIKE等

  ② 避免 % 前缀模糊查询 ⅠB+ Tree Ⅱ 使用丌了索引 Ⅲ 导致全表扫描

7. 减少COUNT(*)( found_rows()/row_count())'

  COUNT(*)的资源开销大,尽量不用少用

8 LIMIT的高效分页

9.用UNION ALL 而非 UNION

  若无需对结果进行去重,则用UNION ALL , UNION有去重开销

10. 分解联接保证高幵发

  高幵发DB不建议进行两个表以上的JOIN

  • 适当分解联接保证高幵发 Ⅰ 可缓存大量早期数据 Ⅱ 使用了多个MyISAM表Ⅲ 对大表的小ID IN() Ⅳ 联接引用同一个表多次

11. GROUP BY 去除排序

12. 同数据类型的列值比较

  原则:数字对数字,字符对字符

  •数值列不字符类型比较

    Ⅰ同时转换为双精度 Ⅱ 进行比对

  •字符列不数值类型比较

     Ⅰ字符列整列转数值 Ⅱ丌会使用索引查询

13. Load data导数据

 

14. 打散大批量更新

··  • 大批量更新凌晨操作,避开高峰

  • 凌晨不限制 • 白天上限默认为100条/秒(

15.Know Every SQL!

  ① mysqlslap MySQL官方提供的性能压力测试工具

  ②EXPLAIN 执行计划

  ③SHOW PROFILE 是mysql提供的可以用来分析当前会话中sql语句执行的资源消耗情况的工具,可用于sql调优的测量。默认情况下处于关闭状态,并保存最近15次的运行结果

  ④Show Slow Log  慢查询日志

  ⑤Show Processlist 显示用户正在运行的线程

  ⑥SHOW QUERY_RESPONSE_TIME(Percona)

  ⑦MySQLdumpslow  慢查询日志分析工具

 

五.约定类军规(5)

1.隔离线上线下

2. 禁止未经DBA确认的子查询上线

3. 永远丌在程序端显式加锁

4. 统一字符集为UTF8

5. 统一命名规范

posted @ 2020-12-18 10:34  胜天、半子  阅读(268)  评论(0编辑  收藏  举报