辅助索引为何不直接保存主键地址,如果保存了主键的地址,就可以不很快的找到记录,而不用再进行二次查找。被这个问题困扰了一阵。答案来了

辅助索引使用主键作为”指针” 而不是使用地址值作为指针的好处是,减少了当出现行移动或者数据页分裂时辅助索引的维护工作,使用主键值当作指针会让辅助索引占用更多的空间,换来的好处是InnoDB在移动行时无须更新辅助索引中的这个”指针”。也就是说行的位置(实现中通过16K的Page来定位,后面会涉及)会随着数据库里数据的修改而发生变化(前面的B+树节点分裂以及Page的分裂),使用聚簇索引就可以保证不管这个主键B+树的节点如何变化,辅助索引树都不受影响。

innodb使用记录数据空间分配,根据文件结构,在插入新数据时,heap是由上而下分配空间的,即向记录尾部追加数据,而对slot分配,是由下向上分配的。

page-header 结构中
page-n-heap:表示页面中记录数,包括已经删除的记录,,page-n-heap的初始为x8002,那么
page-n-heap=x8031,那么页中的记录数为x8031-x8002=x2f,即47,页中有47条记录。

The supremum record represents a key higher than any possible key in the page. Its “next record” pointer is always zero (which represents NULL, and is always an invalid position for an actual record, due to the page headers). The “next record” pointer of the user record with the highest key on the page always points to supremum.

PS:在index page中,最大key值的next record总是指向supermum.

The infimum record represents a value lower than any possible key in the page. Its “next record” pointer points to the user record with the lowest key in the page. Infimum serves as a fixed entry point for sequentially scanning user records.

ACID原则

  • 原子性(Atomicity): 要进行的操作一般为一系列的操作,这些操作要么都被完成,要么都不被完成。这些操作是不可被分割的。
    如果事务是是执行一系列的操作,其中的一条sql执行失败,那么其它那些执行成功的sql要进行撤消操作。
  • 一致性(consistency):数据库从一种一致的状态变成下一种一致的状态。
  • 隔离性(isolation):这个事务中操作的对象,在这个事务提交前,对其它事物都不可见。
  • 持久性(durability):数据被写入磁盘

如果被删除的数据的空间可以被新数据使用,则新数据占用这个空间,而不是从heap_top中申请空间(其实就是追加数据)。如果新数据不能使用已删除数据的空间,则追加数据(从heap_top中申请空间)。注意:这时数据的排序不再按PK key的顺序存放。

参数innodb_ft_cache_size用来控制FTS index Cache的大小,默认为32M,当缓存满时,会将其中的(word,ilist)分词信息同步到磁盘的Auxiliary table中。增大此参数可以提高全文索引的性能,但在宕机时可能需要更长的时间进行恢复。

Multi-Range-Read优化的好处,简称MRR,目的是减少磁盘的随机访问,把随机访问转化为比较顺序的访问,对于IO-bound类型的SQL有很大的性能提升。Multi-Range-Read优化适用于range/ref/eq_ref类型的查询。

mysql 强制指定索引

select * from t_a_index force index(a_b) where a = 1 and b = 1  order by a desc;
select * from t_a_index ignore index(a_b) where a = 1 and b = 1  order by a desc;

索引提示
(1)优化器错误的选择了索引(这种情况很少发生)
(2)查询有多个索引可以使用,使得优化器选择索引的时间大大超过了SQL语句的执行时间

数据库都是通过采样(sample)的方法,来完成Cardinality的统计。
对Cardinality的统计是在存储引擎层面进行的,所以不同的引擎用各自的方法实现。

innodb在进行insert/update操作时,进行Cardinality的统计,但不是每次都进行统计,因为会增加数据库负担。对于数据非常大的表,更不可能进行实时统计,因为那样会影响执行时间,带来非常长的执行时间。

全文索引要借助辅助表auxiliary table,它是持久性的(文件形式),其使用倒排索引inverted index来存储单词及单词所在文档的位置信息

With query expansion, 支持扩展查询(相关性查询)。如查询database,同时也会把含有mysql但不含database的记录也找到。但此功能可能会带来诸多非相关性的查询,要谨慎使用。

在查询select count(*)时,优化器不会使用聚集索引,而是使用辅助索引,因为体积要比聚集索引小,需要的IO操作更少。

Index Condition Pushdown(ICP)优化,当不支持ICP时,先根据索引查记录取出记录,在根据where条件进行过滤。采用ICP时,会在索引中对where条件进行过滤,选出符合条件的,然后再取出记录。即把数据过滤在存储引擎层面完成

慢查询日志:long_query_time:默认值为10s,即超过10s的sql会被记录,但不过记录等于10s的记录。可以以微秒设置时间

相关性的计算依据有四点:

  • word是否同现在文档中
  • word在文档中出现的次数
  • word在索引列中的数量
  • 多个少文档包含此word

二进制日志文件

记录了对数据库的更改操作,但不包括select和show这类操作,因为它们对数据本身没有进行修改。

日志格式ROW:采用ROW格式会大大增加日志文件的体积,在主从复制时,复制是采用二进制格式传输的,因此会增加对带宽的占用。

其体积增大的原因是其记录了每一行的所有信息(所有列信息),所以日志体积会增长很大,而STATEMENT格式只记录基本的SQL语句信息,所以日志文件体积增长较小。