Mysql 性能优化 #
存储引擎 #
使用 Innodb 存储引擎 #
没有特殊要求(即 Innodb 无法满足的功能如:列存储,存储空间数据等)的情况下,所有表必须使用 Innodb 存储引擎(MySQL5.5 之前默认使用 Myisam,5.6 以后默认的为 Innodb)。
Innodb 支持事务,支持行级锁,更好的恢复性,高并发下性能更好。
编码 #
统一使用 UTF8 #
库和表的字符集统一使用 UTF8
表 #
控制单表数据量的大小 #
建议在 500 万以内。500 万并不是 MySQL 数据库的限制,过大会造成修改表结构,备份,恢复都会有很大的问题。
可以用历史数据归档(应用于日志数据),分库分表(应用于业务数据)等手段来控制数据量大小
谨慎使用 MySQL 分区表 #
分区表在物理上表现为多个文件,在逻辑上表现为一个表;
谨慎选择分区键,跨分区查询效率可能更低;
建议采用物理分表的方式管理大数据。
冷热数据分离,减小表的宽度 #
MySQL 限制每个表最多存储 4096 列,并且每一行数据的大小不能超过 65535 字节。
减少磁盘 IO, 保证热数据的内存缓存命中率(表越宽,把表装载进内存缓冲池时所占用的内存也就越大,也会消耗更多的 IO);
更有效的利用缓存,避免读入无用的冷数据;
经常一起使用的列放到一个表中(避免更多的关联操作)。
优先选择小的数据类型 #
列的字段越大,建立索引时所需要的空间也就越大,这样一页中所能存储的索引节点的数量也就越少也越少,在遍历时所需要的 IO 次数也就越多,索引的性能也就越差。
如:
- 将 IP 地址转换成整形数据
- 对于非负型的数据 (如自增 ID, 整型 IP) 来说,要优先使用无符号整型来存储
列定义为 NOT NULL #
索引 NULL 列需要额外的空间来保存,所以要占用更多的空间。
进行比较和计算时要对 NULL 值做特别的处理。
索引 #
限制每张表上的索引数量 #
建议单张表索引不超过 5 个 索引并不是越多越好!索引可以提高效率同样可以降低效率。
索引可以增加查询效率,但同样也会降低插入和更新的效率,甚至有些情况下会降低查询效率。
因为 MySQL 优化器在选择如何优化查询时,会根据统一信息,对每一个可以用到的索引来进行评估,以生成出一个最好的执行计划,如果同时有很多个索引都可以用于查询,就会增加 MySQL 优化器生成执行计划的时间,同样会降低查询性能。
必须有个主键 #
Innodb 是一种索引组织表:数据的存储的逻辑顺序和索引的顺序是相同的。每个表都可以有多个索引,但是表的存储顺序只能有一种。
Innodb 是按照主键索引的顺序来组织表的
- 不要使用更新频繁的列作为主键,不适用多列主键(相当于联合索引)
- 不要使用 UUID,MD5,HASH, 字符串列作为主键(无法保证数据的顺序增长)
- 主键建议使用自增 ID 值
开发 #
避免数据类型的隐式转换 #
避免使用双 % 号的查询条件 #
联合索引 #
在定义联合索引时,如果 a 列要用到范围查找的话,就要把 a 列放到联合索引的右侧。
一个 SQL 只能利用到复合索引中的一列进行范围查询。如:有 a,b,c 列的联合索引,在查询条件中有 a 列的范围查询,则在 b,c 列上的索引将不会被用到。
使用 left join 替代 not in 操作 #
使用 left join 或 not exists 来优化 not in 操作,因为 not in 也通常会使用索引失效。
叶王 © 2013-2024 版权所有。如果本文档对你有所帮助,可以请作者喝饮料。