总的来说,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认为全表扫描更快时,不会使用索引。