Mysql的调优
sql
-
查询sql的尽量不用select * ,而是用select 具体字段 -
如果知道查询结果只有一条或最大/最小一条记录,建议使用limit 1 -
应尽量避免在where子句中使用or来连接条件,这样会全表查询 -
优化like语句,把%写在后面 -
尽量避免在索引列上使用mysql的内置函数 -
应尽量避免在where子句对字段进行表达式操作,这将导致系统放弃使用索引而进行全表扫描 -
关联查询Inner join、left join、right join,优先使用inner join,如果left join,左边表结果尽量少 -
应尽量避免在where子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。 -
使用联合索引时,注意索引列的顺序,一般遵循最左匹配原则 -
如果插入数据过多,考虑批量插入。 -
所以表都必须使用innodb存储引擎,因为innodb支持事物,支持行级锁,更好的恢复性,高性能下性能最好 -
数据库和表字符都为UTF-8 -
所有表和字段都添加注释 -
尽量控制单表数据量的大小,建立控制在500万以内。 -
尽量做到热冷数据分离,减少表的宽度:MySQL 限制每个表最多存储 4096 列,并且每一行数据的大小不能超过 65535 字节。减少磁盘IO,保证热数据的内存缓存命中率(表越宽,把表转载进内存缓冲池所占用的内存也就越大,也就消耗更多的IO); -
禁止在表中建立预留字段 -
禁止在数据库中存储图片,文件等大的二进制数据。 -
禁止在线上做数据库压力测试 -
禁止从开发环境,测试环境直接连接生产环境数据库。 -
避免使用enum类型 -
尽可能把所有列定义为NOT NULL:索引NULL列需要额外的空间来保存,所以占用更多的空间,进行比较和计算时要对NULL值做特别处理 -
使用TIMESTAMP(4个字节)或DATATIME(8个字节)存储时间。 -
和财务相关的金额类数据必须使用decimal类型,非精准浮点:float,double。精准浮点:decimal类型为精准浮点数,在计算时不会丢失精度。可用于存储bigint更大的数据类型。 -
减少同数据库的交互次数 -
对于同一列进行or判断,使用in代替or -
进制使用order by rand()进行随机排序 -
where从句中禁止对列进行函数转换和计算 -
在明显不会有重复值的使用UNION ALL而不是UNION -
拆分复杂的大sql为多个小的sql
索引
1、限制每张表的索引数量,建议单张表索引不超过5个。
索引并不是越多越好,索引可以提高效率同样会降低效率。
索引可以增加查询效率,但同样也会降低插入和更新的效率,甚至有些情况下会降低查询效率
2、禁止给表中的每一个列都建立单独的索引
5.6 版本之前,一个 sql 只能使用到一个表中的一个索引,5.6 以后,虽然有了合并索引的优化方式,但是还是远远没有使用一个联合索引的查询方式好。
3、每个innodb必须有个主键
innodb是一种索引组织表:数据的存储的逻辑顺序和索引的顺序是相同的。每个表都可以有多个索引,但是标的存储顺序只有一种。
Innodb 是按照主键索引的顺序来组织表的
-
不要使用更新频繁的列作为主键,不适用多列主键(相当于联合索引) -
不要使用 UUID,MD5,HASH,字符串列作为主键(无法保证数据的顺序增长) -
主键建议使用自增 ID 值
4、常见的索引列建议
-
出现在select、update、delete语句的where从句的列 -
包含在order by、group by、distinct的字段 -
并不要将符合1和2中的字段都建立一个索引,通常将1、2中的字段建立联合索引效果最好 -
多表join的关联列
5、如何选择列索引列的顺序
建立索引的目的是:希望通过索引进行数据查找,减少随机 IO,增加查询性能 ,索引能过滤出越少的数据,则从磁盘中读入的数据也就越少。
-
区分度最高的放在联合索引的最左侧(区分度=列中不同值的数量/列的总行数) -
尽量把字段长度小的列放在联合索引的最左侧(因为字段长度越小,一页能存储的数据量越大,IO 性能也就越好) -
使用最频繁的列放到联合索引的左侧(这样可以比较少的建立一些索引)
|