总的来说,MySQL数据库优化可以从三个方面来进行
    1.存储引擎的选择
    我们常用的有InnoDB和MyISAM这两种存储引擎,它们的主要区别是
    MyISAM不支持事务,InnoDB支持
    MyISAM是表锁,InnoDB是行锁
    MyISAM不支持外键,InnoDB支持
    MyISAM的查询和新增效率更高

    不难看出,MyISAM更适用于查询多的场合,InnoDB适用于修改和删除。如果要做读写分离,可以考虑读使用MyISAM来提高效率。
    MyISAM为什么快?
    1.InnoDB需要缓存数据块,而MyIASM只缓存索引块。
    2.InnoDB查询要先定位到数据块,再到行。而MyISAM直接记录的文件地址
    3.InnoDB需要维护MVCC的一致性

    2.表设计
    在设计表的时候应该考虑按照3NF。即1.列应具备原子性,不可再拆分 2.行应该唯一,并且有其对应的唯一标识符 3.能通过关联查询得到的数据不应该设置冗余字段。
    当然,有时为了提高效率避免联表查询应该考虑设置反3NF,设置相关的冗余字段。

    还有就是,如果事先能确定长度的尽量用char,它虽然占空间但是因为定长所以效率更高,比如姓名,完全没必要弄varchar。能使用TINYIINT的不同INT,能用INT的不同BIGINT
    如果一张表字段太多,考虑做垂直分表
    如果能预期到一张表的数据会很大,做水平分表

    3.索引
    索引的分类:
    唯一索引、主键索引、普通索引、全文索引

    按照组合方式又有组合索引和单列索引

    InnoDB和MyISAM的索引结构有何不同:
    最大区别的在于它们使用索引的方式不同,虽然都是B+Tree,但是MyISAM是非聚簇索引,InnoDB是聚簇索引
    除了共有的.frm文件存储表结构外,InnoDB将索引和数据都存放在ibdata1文件中,而MyISAM是将索引和数据分别存放在.MYI和.MYD中。
    InnoDB的辅助索引的叶子节点中存放的是主键索引的id,也就是说当通过辅助索引查询时会查两棵树,这个操作就叫回表。而MyISAM的主键索引和辅助索引叶子节点都存放的是数据所在的地址,通过辅助索引可以直接查数据不需要走主键索引。

    哪些地方适合建立索引?
    where和oder by中使用的多的字段可以建立索引
    数据不经常进行修改的
    唯一性较强的

    4.索引的优化
    1.通过指令先建立慢查询,找到慢查询的语句
    set global long_query_time=1 设置超过多少秒为慢查询。也可以通过添加到my.ini让MySQL每次启动都加载这个配置
    set global slow_query_log=true 开启慢查询记录
    set global log_queries_not_using_indexes=ON 记录所有未使用索引的SQL
    show status like ‘slow_queries’ 查询慢查询次数

    2.通过EXPLAIN命令查看当前SQL语句分析
    EXPLAIN SELECT * FROM user
    其中有几个比较重要的参数

    type:查询类型。从低到高常见的三种是ALL、Index、Range。ALL表示全表扫描,Index表示遍历整个索引树。range表示只查询某个范围。一般我们要求查询至少达到range
    key:实际使用到的是哪个索引
    rows:得到数据大致需要遍历的条数
    Extra:一些重要的额外信息

    3.通过分析之后我们就可以对索引进行优化

    1.避免使用左%,像%aa这种。左%会导致不走索引(其实不完全是。如果SELECT后面只查索引字段或者索引+主键字段,其实左%也能走索引,只是会导致查询效率降低,从range到index)
    2.避免使用in,not in,not exist等,会导致索引失效。可以使用exist替代in
    3.谨慎使用or。如果是单列索引使用or,那么or前后必须都是索引字段,否则不会走索引。如果是复合索引,那么根据最左原则,使用or会导致不走索引。(最左原则:是针对复合索引的。也就是说复合索引的最左边的索引必须出现在查询条件中,只是单个右边的索引出现是不会使用复合索引的)
    4.如果索引字段是字符串,一定要用‘’包起来,否则不走索引
    5.查询null值不会走索引。所以我们应该在设计表的时候都设置not null,并给默认值。
    6.查询条件进行过运算,不会走索引,因为不确定计算后的值
    7.不要使用select * ,用具体的字段来代替,不要返回不需要的字段。
    7.当MySQL认为全表扫描更快时,不会使用索引。