本文是自己在开发使用mysql数据库过程中的总结,欢迎大家指正。

索引的优化

  1. 只要列中含有null值,就最好不要在此例设置索引,复合索引如果有null值,此列在使用时也不会使用索引
  2. 尽量使用短索引,如果可以,应该指定一个前缀长度
  3. 对于经常在where子句使用的列,最好设置索引,这样会加快查找速度
  4. 对于有多个列where或者order by子句的,应该建立复合索引
  5. 对于like语句,以%或者‘-’开头的不会使用索引,以%结尾会使用索引
  6. 索引不要冗余和重复,索引不宜过多
  7. 如果有必要,可以考虑覆盖索引(不用回表操作)

 

sql语句的优化

  1. 查询时,能不要*就不用*,尽量写全字段名;(理由:只取需要的字段节省资源和网络开销,select * 可能不会使用覆盖索引而造成回表查询)
  2. 如果知道查询结果只有一条或者只要最大/最小一条记录,建议加上limit 1;(理由:只要找到一条记录就不用继续扫描查找(唯一索引的确定值查询例外,可以不加limit 1))
  3. 尽量避免在where子句中使用or来连接条件
  4. 大部分情况连接效率远大于子查询
  5. 多使用explain和profile分析查询语句
  6. 查看慢查询日志,找出执行时间长的sql语句优化
  7. 多表连接时,尽量小表驱动大表,即小表 join 大表
  8. 在千万级分页时不能直接使用limit,(具体看下面limit查询优化)
  9. 对于经常使用的查询,可以开启缓存
  10. 尽量不要在列上进行运算(函数操作和表达式操作)
  11. 尽量不要使用not in和<>操作
  12. 如果要操作的数量很大,可以考虑批量
  13. 推荐使用union all连接数据,相比union效率更高(注意有无重复数据)

 

表的优化

  1. 永远为每张表设置一个 id
  2. 表的字段尽可能用not null,考虑用默认值代替null
  3. 使用 enum 而不是 varchar
  4. 字段长度固定的表查询会更快
  5. 把 IP 地址存成 unsigned int,数据库可以自定义函数ip2int,int2ip来辅助
  6. 把数据库的大表按时间或一些标志分成小表
  7. 将表分区

 

limit查询优化

  • 子查询优化法:先找出第一条数据(即通过条件查询查询limit的第一条),然后大于等于这条数据的id就是要获取的数据。
select xx
from table
where id >= (
    select id from table
    limit 1000,1
)
limit 100;
  • 反向查找优化法:当偏移超过一半记录数的时候,先用排序,这样偏移就反转了

 

主从同步延迟原因及解决办法

  1. 因为主服务器要负责更新操作, 他对安全性的要求比从服务器高, 所以有些设置可以修改,比如sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之类的设置,而slave则不需要这么高的数据安全,完全可以讲sync_binlog设置为0或者关闭binlog,innodb_flushlog, innodb_flush_log_at_trx_commit 也 可以设置为0来提高sql的执行效率 这个能很大程度上提高效率。另外就是使用比主库更好的硬件设备作为slave。
  2. 把一台从服务器过渡作为备份使用, 而不提供查询, 那当他的负载下来了, 执行relay log 里面的SQL效率自然就高了。
  3. 增加从服务器,这个目的还是分散读的压力, 从而降低服务器负载。