Mysql常见优化方案 - Wangxiaoman/tech-note GitHub Wiki

  • 结构:B+tree

  • 最常用引擎:Innodb、MyISAM、Memory

  • 索引:

    Innodb:主键索引是聚簇索引(auto_increment的键必须为整形主键),二级索引叶子节点是主键ID

    MyISAM:主键索引非聚簇,主键索引和二级索引的叶子节点存储的都是实际数据的地址

    利用到索引需要满足最左前缀原则

  • Mysql的查询缓存

    Mysql的查询缓存比较苛刻,相当于把整个sql语句作为key值,结果作为value放到了缓存中。如果你的下次查询语句发生了变化,那么就不能利用到缓存,所以想使用到这部分缓存,需要保证sql的恒定

  • 尽量避免使用default null的字段

    一反面是查询的时候会更加复杂,比如针对varchar类型的字段,empty和null的区分(实际在oracle中empty和null是等价的);

    再有是null实际是需要占额外的存储空间(相对于empty来说);

    如果主键索引中有值为null,那么可能会引起主键的实效;

  • 拆分比较大的select和insert语句

    一般在工程上和mysql进行交互都是通过长连接,如果sql或者返回结果很大,都会对IO造成很大的压力,一般我们是将这些语句拆分。比如是我要提交1w条record,那么我可以分为5次处理,每次提交2k条。

insert into table(a,b) values(1,1),(2,2),(3,3)....
  • sql语句的一些点:
select * from table limit 1000; -- (注意查询返回的数据量)
select * from table where xxx> 100 and ...; -- (注意索引的使用)
select * from table where substring(title,'a',-1) > 'a'; --(where条件后面,不要在字段上加函数进行查询)
select * from table where a like ‘%xx%’; --(无法利用索引,like xx%可以)
select * from table order by rand(); -- 注意不要这么使用,如果真想要一些随机结果,可以提前处理,然后 limit获取

  • 利用explain sql来优化sql

  • 如果确定要使用表上的某个索引,可以在sql上使用USE INDEX 或者 FORCE INDEX

    FORCE INDEX 会指定这个SQL在所有查询下都强制走某一个索引;USER INDEX 如果认为全表的顺序扫描更优,那么会使用全表扫描