本文借鉴很多网上优化的经验,并且加上自己实际的sql优化经验而成
一、核心
1、不要在sql中进行运算,数据库是用来查询和存储的,一般在数据库服务器采集的时候会使用很好的存储设备,而不是cpu,
2、控制单表中的数据量,当数据库中数据很多的时候,sql优化的再好也是无力的,可以进行分表
3、控制表中列的数量,一般在20~60之间,越少越好
4、平衡范式于冗余,三范式是死的,人和业务是活的,效率优先,可以牺牲范式,比如在查询进行省市县的时候可以直接使用不用冗余
5、拒绝3B;拒绝大事物。拒绝大查询,拒绝大批量,因为这些会占用太多时间,导致后续的对数据库的操作堵塞,而且大查询会导致全表扫描,同时不会把查询放到数据库自己的缓存中
二、字段类型
6、用好字段类型
tinyint(1Byte)
smallint(2Byte)
mediumint(3Byte)
int(4Byte)
bigint(8Byte)
bad case:int(1)/int(11)
7、字符转化为数字
8、优先使用enum
9、避免使用null字段;null很难优化、null字段的索引或占用额外的空间,null的复合索引无效,可以加上默认值
10、少用text/blob/clob;varchar的效率比他们高的多,如果必要可以拆表
11、谨慎添加索引;索引并非越多越好,增加索引会导致插入变慢,因为要给条该数据增加索引,列中空比较多或者只有几个相同的字段如性别,避免
12、不要在索引列上进行运算操作;不只是索引列上,所有的都要尽量避免运算,参照上面
13、字符字段尽量建前缀索引,字符太长的话建前缀索引
14、主键推荐使用自增长
15、避免使用外键,可以在程序中控制
三、sql优化
16、sql语句尽量简单,大sql拆成小sql,减少锁时间;
18、尽量缩短事物的时间:
19、减少触发器、存储过程、视图的创建
20、不使用select *:很消耗cpu、内存
21、or改写成in或者union或者exists:in的个数控制在200以内
22、避免使用like '%a%' 这样会全表扫描,可以使用 '%a'
23、慎用count(*):使用count(1)或者count(主键)要高效的多
24、limit 高效分页,limit第一个数字越大,效率越低
select id from t limit 10000, 10;
=>
select id from t where id > 10000 limit 10;
25、使用union all替代union:union有去重开销
26、使用load data到数据,比insert高效率20倍
27、使用性能分析工具,避免全表扫描
28、where子句中不要使用!=或者<>
29、避免在where条件的子句的左侧写函数,这样会无法使用索引导致全表扫描,
30、能用distinct去重就不要用group by
31、可以合理使用临时表和复合索引,视图
32、查询的表关联尽量少于5个
33、尽量使用join来代替子句
34、尽量早过滤索引条件,mysql是从左往右执行,所以能过滤掉大量数据的条件,放到左边
35、尽量每一条sql都要使用explain:来查看是否有优化的余地