在互联网公司MySQL的使用很是普遍,你们常常会有MySQL性能优化方面的需求。整理了一些在MySQL优化方面的实用技巧。缓存
整数一般是标识列最好的选择,由于它们很快而且可使用AUTO_INCREMENT
性能优化
彻底“随机”的字符串(如:MD5()
、SHA1()
或者UUID()
等产生的字符串)会任意分布在很大的空间内,会致使INSERT
以及一些SELECT
语句变的很慢服务器
若是但愿查询执行得快速且并发性好,单个查询最好不要作太多的关联查询(互联网公司很是忌讳关联查询),利用程序来完成关联操做并发
若是须要对一张比较大的表作表结构变动(ALTER TABLE
操做增长一列),建议先拷贝一张与原表结构同样的表,再将数据复制进去,最后经过重命名将新表的表名称修改成原表的表名称。由于在变动表结构的时候颇有可能会锁住整个表,而且可能会有长时间的不可用函数
避免多表关联的时候能够适当考虑一些反范式的建表方案,增长一些冗余字段性能
若是不是按照索引的最左列开始查找,则没法使用索引学习
全部的非聚簇索引都须要先经过索引定位到对应的主键,而后在到聚簇索引查找数据,因此在定义主键索引的时候必定要谨慎优化
只有当索引的列顺序和ORDER BY
子句的顺序彻底一致,而且全部列的排序方向(倒序或者正序)都同样时,MySQL才可以使用索引来对结果作排序。有一种状况下ORDER BY
子句能够不知足索引的最左前缀的要求,就是前导列为常量的时候。设计
在使用like
来匹配字符串类型的字段的值时,尽量的使用前缀匹配like ‘XX%’
,避免使用 like ‘%XX’
code
哈希索引是基于哈希表实现的,只有精确匹配索引全部列的查询才有效,也不遵循索引的最左匹配原则
当服务器须要对多个索引作联合操做时(一般有多个OR
条件),建议修改为UNION
的方式,这样方便命中索引
对于如何选择索引的列顺序有一个经验法则:将选择性最高的列放到索引最前列
尽量多的使用覆盖索引(若是一个索引包含或者说覆盖全部须要查询的字段的值,咱们就称之为覆盖索引),经过EXPLAIN
的Extra
列能够看到“Using index”信息
当ID为主键时,建立索引(A),至关于建立了(A)和(A, ID)两个索引
表中的索引越多对SELECT
、UPDATE
和DELETE
操做速度变慢,同时占用的内存也会比较多
InnoDB在二级索引上使用共享锁,可是访问主键索引须要排他锁
尽量的使用WHERE IN
和WHERE BETWEEN AND
的方式来进行范围查询
LIMIT
的偏移量越大性能越慢
编写查询语句时应该避免单行查找、尽量的使用数据原生顺序从而避免额外的排序操做,并尽量使用索引覆盖查询
对于低效的查询,一般从两个方面来分析:
通常MySQL可以使用如下三种方式应用WHERE
条件,从好到坏依次为:
MySQL从设计上让链接和断开链接都很轻量级,在返回一个小的查询结果方面很高效。在一个通用服务器上,也可以运行每秒超过10万的查询,一个千兆网卡也能轻松知足每秒超过2000次的查询,MySQL内部每秒可以扫描内存中上百万行数据
在删除大量数据时,建议每次删除一小批量数据后,暂停一下子再作下一次的删除
不管如何排序都是一个成本很高的操做,因此从性能角度考虑,应尽量避免排序或者尽量避免对大量数据进行排序
COUNT()
函数有两种不一样的做用:它能够统计某个列值的数量,也能够统计行数。最简单的就是经过COUNT(*)
来统计行数
关联查询的时候要确保关联的字段上有索引
在数据量很大而且历史数据须要按期删除的状况下,能够考虑使用分区表
若是定了的索引列和分区列不匹配,会致使查询没法进行分区过滤
外键约束尽量避免,一般经过程序来实现,心中要有外键
触发器、存储过程、自定义函数等最好不要使用
尽量的利用查询缓存,若是在写查询语句的时候有一些不肯定的数据(NOW()
或者CURRENT_DATE()
等)时,则不会被缓存
用多个小表代替一个大表对查询缓存有好处
批量写入时只须要作一次缓存失效,因此相比单条写入(每写入一次,缓存就失效)效率更好,对于写密集型的应用,直接禁用查询缓存
若是缓存的空间太大,在过时操做的时候可能会致使服务器僵死
以上是我的在工做中的经验总结,若是有描述错误的地方但愿你们能够帮忙指出,一块儿交流学习!