MySql优化建议

MySQL数据库开发三十六条军规

一.核心军规

尽量不在数据库做运算,cpu计算的事务必移至业务层;
控制表、行、列数量(【控制单张表的数据量 1年/500W条,超出可做分表】,【单库表数据量不超过300张】 、【单张表的字段个数不超过50个,多了拆表】)
三大范式没有绝对的要使用,效率优先时可适当牺牲范式
拒绝3B(拒绝大sql语句:big sql、拒绝大事物:big transaction、拒绝大批量:big batch);

二.字段类军规

用好数值类型(用合适的字段类型节约空间); 如:一个字段注定就只有1跟2 要设计成 int(1) 而不是 int(11)
字符转化为数字(能转化的最好转化,同样节约空间、提高查询性能);
如,一个字段注定就只有1跟2,要设计成int(1) 而不是char(1) 查询优化如:字段类型是 char(1) 查询应当where xx='1' 而不是 xx=1 会导致效率慢
避免使用NULL字段
NULL字段很难查询优化、NULL字段的索引需要额外空间、NULL字段的复合索引无效;

如: 要设计成 c int(10) NOT NULL DEFAULT 0
而不是 c int(10) NOT NULL;
少用text/blob类型(尽量使用varchar代替text字段), 需要请拆表
不在数据库存图片,请存图片路径,然后图片文件存在项目文件夹下。

三.索引类军规

合理使用索引
改善查询,减慢更新,索引一定不是越多越好;

如:不要给性别创建索引
字符字段必须建前缀索引;
pinyin varchar(100) DEFAULT NULL COMMENT '小区拼音',

KEY idx_pinyin (pinyin(8)),
不在索引做列运算;
如:WHERE to_days(current_date) – to_days(date_col) <= 10
改为:WHERE date_col >= DATE_SUB('2011-10- 22',INTERVAL 10 DAY);
InnoDB主键推荐使用自增列
主键建立聚簇索引,主键不应该被修改,字符串不应该做主键

如:用独立于业务的AUTO_INCREMENT
不用外键(由程序保证约束);

四.SQL类军规

sql语句尽可能简单
一条sql只能在一个cpu运算,大语句拆小语句,减少锁时间,一条大sql可以堵死整个库;
简单的事务;
避免使用trig/func(触发器、函数不用,由客户端程序取而代之);
不用select (消耗cpu,io,内存,带宽,这种程序不具有扩展性);
如:select a ,b,c 会比 select
好 只取需要列
OR改写为 IN
如:where a=1 or a=2 改 a in(1,2)
OR改写为UNION
针对不同字段 where a=1 or b=1
改:select 1 from a where a=1 union select 1 from a where b=1
避免负向%;
如 where a like %北京% 改为 where a like '北京%'
limit高效分页(limit越大,效率越低);
如 Limit 10000,10 改为 where id >xxxx limit 11
使用union all替代union(union有去重开销);
高并发db少用2个表以上的join;
使用group by 去除排序加快效率;
如:group by name 默认是asc排序
改:group by name order by null 提高查询效率
请使用同类型比较;
如:where 双精度=双精度 数字=数字 字符=字符 避免转换导致索引丢失
打散大批量更新;
如:在凌晨空闲时期更新执行

五.约定类军规

隔离线上线下,
如:开发用dev库,测试用qa库,模拟用sim库,
线上用线上库,开发无线上库操作权限
不在程序端加锁,即外部锁,外部锁不可控,会导致 高并发会炸,极难调试和排查
统一字符 UTF-8 校对规则 utf8_generalci 出现乱码 SET NAMES UTF8
统一命名规范,库表名一律小写,索引前缀用idx
库名 用缩写(2-7字符),不使用系统关键字保留字命名