在日常开发中,mysql存储引擎默认是用innoDB,存储引擎分为innoDB,myISAM,memory,innoDB支持事务,myISAM不支持事务,memory是在内存中,不存储在磁盘,所以memory适用于临时表,特性是mysql服务器重启之后,内存里的数据就会消失。

一条数据的查询过程是mysql客户端与服务端之前的连接过程,先通过tcp与ip连接客户端,然后转码解析,查询缓存,sql语句优化,前面的都属于service层,后面的是访问存储引擎,最后再把数据返回给客户端。根据电脑和sqlservice之类的不同,发送sql语句的编码格式也会不同,gbk支持1~2个字符集,utf8支持1~3个字符集。Mysql服务器接收后会吧字符集转码为自己的字符集,character_set client,character set connection,character set result,分别用于接收发过来的字符串,转换成字节串,之后再把数据返回给客户端,一般在大数据的情况下,会吧三个值设置成同一个字符集,用系统参数set names ‘’,保证字符集的相互转换之间避免性能消耗。查询缓存的时候如果sql完全一致,不管从哪个客户端发来的sql,会直接从缓存中查询,就没必要进行下面的操作,但sql里面如果有一点不一样,或者用了函数,比如now()日期等,也会放弃缓存。之后就会sql语句优化,sql优化是通过mysql自己计算的,innoDB会计算出粗略值,myISAM会计算出精确值,通过各种索引 或者全表查询,计算出最后到底哪个成本最低。

最后访问innoDB存储引擎,innoDB存储引擎的数据存储在b+tree的节点里,与b-tree不同的是,b+tree在内节点也就是非叶子节点不存储数据,这样高度更低,效率更高。

索引就是存在b+tree里,索引分为聚簇索引,二级索引,复合索引,覆盖索引,前缀索引,每条数据分为额外数据,真实数据,和隐藏列数据,隐藏列数据就包含着row_id,trx_id,roll_pointer,row_id不是必须的,没有主键索引和唯一索引的时候,才会创建row_id,trx_id是事务id,roll_pointer会指向undo日志,通过mvcc管理,mvcc有一个readView链表,链表由m_ids,max_id,min_id,create_trx_id组成第一位是显示在所以b+树的数据,后面的数据都是历史修改的数据,undo日志,然后根据trx_id来判断当前事务里显示哪个值。

聚簇索引又称为主键索引,二级索引就是其他列组成的索引,复合索引是由多个二级索引组成,有最左原则,最左原则是当范围查询的时候,必须满足最左边的索引列是等值的。主键索引和二级索引有两个不同的b+树,主键索引里的叶子节点存储了所有的用户记录的真实数据,非叶子节点存储的是页码和主键id,二级索引存储的是索引的真实数据,当用覆盖索引查询的时候,直接查询二级索引b+树就能返回数据给用户,但如果select查询的数据里面还有不是索引的列,这时候查询是先通过二级索引的b+树查询,之后再通过查询的id,回表查询主键的b+树。前缀索引指一个列的string太长,于是选择前面一段来建立索引。