目录

mysql优化

分析效率

show status like “xxx” 查询一些msyql性能参数

  • connections: 连接数据库服务端的次数
  • slow_queries:慢查询次数
  • com_select:查询次数
  • com_insert:插入次数等

慢查询日志分析

MySQL的慢查询日志是MySQL提供的一种日志记录,用来记录在MySQL中响应时间超过阈值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中(日志可以写入文件或者数据库表,如果对性能要求高的话,建议写文件)。默认情况下,MySQL数据库是不开启慢查询日志的,long_query_time的默认值为10(即10秒,通常设置为1秒),即运行10秒以上的语句是慢查询语句。

修改my.cnf文件,增加或修改参数slow_query_log 和slow_query_log_file后,然后重启MySQL服务器,如下所示

slow_query_log =1

slow_query_log_file=/tmp/mysql_slow.log

优化查询

联合索引最左前缀原则

复合索引遵守「最左前缀」原则,查询条件中,使用了复合索引前面的字段,索引才会被使用,如果不是按照索引的最左列开始查找,则无法使用索引。 比如在(a,b,c)三个字段上建立联合索引,那么它能够加快a|(a,b)|(a,b,c)三组查询的速度,而不能加快b|(b,a)这种查询顺序。 另外,建联合索引的时候,区分度最高的字段在最左边。

不要在列上使用函数和进行运算

不要在列上使用函数,这将导致索引失效而进行全表扫描。 例如下面的 SQL 语句: select * from artile where YEAR(create_time) <= ‘2018’; 即使 date 上建立了索引,也会全表扫描,可以把计算放到业务层,这样做不仅可以节省数据库的 CPU,还可以起到查询缓存优化效果。

负向条件查询不能使用索引

负向条件有:!=、<>、not in、not exists、not like 等。 select * from artile where status != 1 and status != 2; 可以使用in进行优化: select * from artile where status in (0,3)

使用覆盖索引

所谓覆盖索引,是指被查询的列,数据能从索引中取得,而不用通过行定位符再到数据表上获取,能够极大的提高性能。

可以定义一个让索引包含的额外的列,即使这个列对于索引而言是无用的。

避免强制类型转换

当查询条件左右两侧类型不匹配的时候会发生强制转换,强制转换可能导致索引失效而进行全表扫描。 如果phone字段是varchar类型,则下面的SQL不能命中索引: select * from user where phone=12345678901; 复制代码可以优化为: select * from user where phone=‘12345678901’;

并不是所有的类型转换都会让索引失效。 数字和字符串比对时,是把字符串转为数字了。 例子:user表name和age都分别有索引。

explain select * from user where age ='5';//字符串转为数字了,刚好age是数字,依然能用上索引

explain select * from user where name =8; //此时name索引失效

范围列可以用到索引

范围条件有:<、<=、>、>=、between等。

范围列可以用到索引,但是范围列后面的列无法用到索引,索引最多用于一个范围列,如果查询条件中有两个范围列则无法全用到索引

更新频繁、数据区分度不高的字段上不宜建立索引

更新会变更B+树,更新频繁的字段建立索引会大大降低数据库性能。 「性别」这种区分度不大的属性,建立索引没有意义,不能有效过滤数据,性能与全表扫描类似。 区分度可以使用 count(distinct(列名))/count(*) 来计算,在80%以上的时候就可以建立索引。

避免使用or来连接条件

应该尽量避免在 where 子句中使用 or 来连接条件,因为这会导致索引失效而进行全表扫描,虽然新版的MySQL能够命中索引,但查询优化耗费的 CPU比in多。 Or的时候只有or前后都是索引才有效。

模糊查询

前导模糊查询不能使用索引,非前导查询可以。

分页优化

大的分页数据效率比较差,可以使用子查询先获得对于的Id,然后再查。或者通过id的返回。不过这些都是要id是有序的才行。

如果明确知道只有一条结果返回,limit 1 能够提高效率 虽然自己知道只有一条结果,但数据库并不知道,明确告诉它,让它主动停止游标移动。

旧版本中可以使用limit n,-1;来获取偏移量到最后的数据,新版本中不能这样了,官方建议使用一个较大的数字来实现。

插入的优化

  • 如果要插入大量的数据可以在插入前暂停索引、唯一校验、外键检查。不过看存储引擎是否支持。
  • load data infile比insert语句快。