Mysql-优化

数据库优化也就是提升数据库的读写能力,我把他分为多个层次来讲
1.数据库设计
数据库设计存在三范式
第一范式就是无重复的域。
第二范式就是在第一范式的基础上属性完全依赖于主键。
第三范式就是在满足第一范式的基础上,任何非主属性不得传递依赖于主属性。
设计表时要注意范化和反范化,
遵循范式好处就是能够消除或者是减少数据的冗余,这样数据就会小可以更好的放入内存,执行操作会快。重复数据少到时更新更少的数据,速度会快。
范式当然也有坏处,遵循范式使得查询会关联多个表,关联多个表可能会使一些索引策略无效。例如范式化可能会将列放入多个表中,而原本这些列可以属于同一个索引。

所以我们设计表时要根据具体的业务来设计表结构,表中可以存适当的重复数据来减少关联查询数量,但是重复数据更新时需要更新多表。这些都是根据具体业务场景做出判断。

2.查询设计
1.请求了不必要的数据
优化数据访问,是不是客户端请求了大量不必要的数据。有些査询会请求超过实际需要的数据, 然后这些多余的数据会被应用程序丢弃,这样增加mysql服务器和网络io的负担,也会消耗应用服务器的性能。例如查询不必要的列然后在应用服务器进行过滤 ,或者select *但是只取其中几条数据。

2.mysql扫描了额外记录
在评估査询开销的时候, 需要考虑一下从表中找到某一行数据的成本。 MySQL 有好几种访问方式可以査找并返回一行结果。 有些访问方式可能需要扫描很多行才能返回一行结果, 也有些访问方式可能无须扫描就能返回结果。expain中的type定义了访问类型,全表扫描,索引扫描,fanwei范围访问或者是单值访问,扫描的数据量从大到小。通过建立适当的索引来减少mysql的扫描行数。

3.索引设计
优秀的所有是对查询优化最有效的手段。innodb索引使用b+tree的数据结构。存储方式采用聚簇索引。主键索引的叶子项有行数据,二级索引叶子项存的是主键。聚簇索引进行二级索引查询时如果没发生缓存覆盖则需要回表查询,但是优点就是当数据位置发生变动,不像非聚簇索引需要变动叶子节点的数据物理地址。

索引优点
减少查询数据时的扫描量
帮助服务器避免排序和临时表
将随机io变为顺序io

这里要注意索引并不是越多越好,1.索引也是需要占用空间的 2 索引影响新增操作

前缀索引
当需要在很长的数据中建立索引例如blob test或者是很长的varchar。如果直接在字段上建立索引那么索引会变得又大又慢。mysql不允许出现很大的索引,所以这里需要使用前缀索引。
前缀索引的诀窍就是需要索引即短(数据量小),又长(具有更高的选择性)。短就是说节省空间,长意味着通过索引得到数据要大概率不被回表扫面过滤。

多列索引
当出现多个where条件时考虑建立多列索引而不是为每个列添加索引。mysql会对具有多个where条件(and or)并且每个列都有独立索引的数据进行优化,使用多个查询的联合。explain中的extra中显式using union。
1.当服务器需要对多个索引做相交操作时(多个and),通常说明需要一个多列索引而不是多个列的索引
2.当服务器需要对多个索引做联合操作时,(多个or操作),服务器将会消耗大量的cpu资源在排序,缓存,过滤操作上。
所以如果在expain中看到索引合并,应该好好的检查查询与表结构,看看是不是最优的。

多列索引的顺序问题
where条件中出现多个and并且不需要考虑排序和分组时,最好的顺序就是将选择性大的列放在左边,这样就能快速的过滤出需要的行。对于where子句中只使用了 部分前缀列的查询来说选择性也越高。也需要根据不同查询语句的频率来调整索引的顺序。

索引覆盖
当索引中含有查询需要返回的字段时,可以不需要进行二次查询表,直接返回数据,这样效率会提升很大。需要多列索引中覆盖了查询条件,并且覆盖了查询返回字段。索引存在内存中也都是顺序储存的,当排序能够使用索引覆盖的话,效率提升会非常大。

索引扫描来做排序
mysql有两种排序方式,一种是文件排序,另一种是索引扫描排序。如果explain出来的type是index,则表明使用了索引扫描排序。
使用索引顺序扫描通常是很快的,只需要从一条索引记录移动到下一条索引记录,但是如果扫描不能返回查询所需要的列,则需要按照索引的顺序一条一条回表找到对应的列。这基本上是随机io。这样的话效率往往不如按顺序全表扫描。

mysql可以使用同一个索引既可以满足查找行,又可以满足排序查找。总之当出现排序查找时,最好就是
1.能利用索引的顺序,即不需要进行文件排序
2.能利用索引过滤条件 where中建立索引,即使用索引过滤不匹配行数据,不需要回表在进行过滤。
3.能利用索引覆盖,即不需要回表查找需要返回的列。

删除冗余的索引
mysql会单独维护所有的索引,并且优化器在优化查询时也需要zhu诸葛进行考虑,影响性能。建立索引可以提高查询的性能,但是索引自己是一个索引列和主键的数据结构,当主表进行新增,修改,删除时二级索引都会做出对应的变动。所以我们需要删除冗余的索引。例如存在索引(A,B),则索引(A)就是冗余的。原因其实就是mysql的索引原理,不懂的看上篇博文。存在索引(A)则索引(A,ID)也是冗余的,因为二级索引的叶子项就包含了主键。

4.缓存
可以使用缓存来减少数据库的读压力,但是要注意缓存的使用,注意数据一致性,缓存穿透,缓存雪崩,缓存击穿等问题。
通过引入别的组件来进行数据库优化,这里往往会带来系统的复杂性。
5.数据库架构
如果实在没办法了就只能拓展数据库的架构了,进行水平拆分(分表),垂直拆分(分库)等操作。不仅麻烦,而且会引入更多的问题。

你可能感兴趣的:(mysql)