1.MyISAM和InnoDB
InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引。
InnoDB的主键索引的叶子节点存储着行数据,因此主键索引非常高效。
MyISAM索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据。
InnoDB非主键索引的叶子节点存储的是主键和其他带索引的列数据,因此查询时做到覆盖索引会非常高效。
锁的粒度:My是表级锁,InnoDB行级和表级更适合并发
My不支持外键和事务,InnoDb是支持的
My的数据和索引是分开存储,In是集中存储
2.索引的类型
1.主键索引
2.唯一索引
3.普通索引
4.全文索引?
3.聚簇索引和非聚簇索引
1.B+Tree有哪些索引类型
根据叶子结点的数据类型,可以分为主键索引和非主键索引。
主键索引的叶子节点存的数据是整行数据(即具体数据)。在InnoDB里,主键索引也被称为聚集索引(clustered index)。
非主键索引的叶子节点存的数据是整行数据的主键,键值是索引。在InnoDB里,非主键索引也被称为辅助索引。
辅助索引与聚集索引的区别在于辅助索引的叶子节点并不包含行记录的全部数据,而是存储相应行数据的聚集索引键,即主键。当通过辅助索引来查询数据时,需要进过两步:首先,InnoDB存储引擎会遍历辅助索引找到主键。然后,再通过主键在聚集索引中找到完整的行记录数据。
2.创建索引的原则
1)最左前缀匹配原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配。
比如我把表的a和b两列组成的联合索引:score_age,查询的时候;
where a = 100 and b = 20这种可以生效
where a= 100 也可以生效
where b = 20 索引就不生效了
遇到以范围查询时为止,这句话的意思是该范围查询会使用索引,但是之后的就不会使用了
where a > 90 也会使用索引,索引列是score
where a > 90 and b = 90 此时索引列还是只有score
where a = 90 and b >20 此时两者都会用到索引,索引列是score 和age
2)较频繁作为查询条件的字段才去创建索引
3)更新频繁字段不适合创建索引
4)若是不能有效区分数据的列不适合做索引列(如性别,男女未知,最多也就三种,区分度实在太低)
5)尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。
6)定义有外键的数据列一定要建立索引。
7)对于定义为text、image和bit的数据类型的列不要建立索引。
4.mysql的事务说明
原子性:事务中的所有操作要么全部执行,要么全部不执行,不会停留在中间的某个操作
一致性:事务前后,数据库中的数据的完整性没有被破坏,比如账户少的是其他的多的维持不变。
隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
脏读:
不可重复读:
幻读:
1.四种事务的隔离级别
1、读未提交(Read uncommitted):开启两个事务 事务A可以读取到事务B 已经修改但是没有提交的结果,会导致脏读
2、读已提交(Read uncommitted)只能读取到已经提交的事务变化,会有不可重复读
3、可重复读:事务一旦开启后读到的数据始终是同一个 在这个过程中无论其他事务对这个事务做了何种操作,会导致幻读。
4、串行化(Serializable):当一个事务中有对某张表A做修改或插入删除操作时候,其他事务是不能进行改操作的;
5. mysql中的锁
6.分库分表
1.水平分表
即将表按照行数进行扩充,比如:1~10000为第一个表,10001~20000为第个表这种,但是存在一个问题读和写都会访问新的数据
hash取模可以解决,扩容和迁移麻烦,导致hash值失效
一致性hash,使用圆环的方式,将节点放至环上,之后再添加,对之前的没有影响
2.垂直分表
将一个表按照字段分成多个表,一个表只使用之前的一部分字段
3.垂直分库
是指按照业务将表进行分类,分布到不同的数据库上面,每个库可以放在不同的服务器上,它的核心理念是专库专用。
4.水平分库
是把同一个表的数据按一定规则拆到不同的数据库中,每个库可以放在不同的服务器上。水平分库是把不同表拆到不同数据库中,它是对数据行的拆分,不影响表结构
7.调优
1.表结构和索引
分库分表,读写分离;
为字段选择合适的数据类型;
将字段多的表分解成多个表,增加中间表;
混用范式与反范式,适当冗余;
为查询创建必要索引,但避免滥用;
2.sql语句优化
寻找最需要优化的语句:分析慢查询日志;
利用分析工具:explain(分析语句执行计划,是否使用索引)、profile(分析某个语句分布耗时);
避免使用SELECT *,只取需要的列;
尽量使用prepared statements(性能更好,防止SQL注入);
使用索引扫描来排序。