数据页结构
·数据删除后记录并没有马上被删除,而是被打上了删除标记,并被记录到一个垃圾链表中,之后若有新纪录来,它们则可能覆盖被删除的记录占用的存储空间。
·页内数据组成单向链表,且再次进行了分组,每组最后一条数据顺序存储在靠近页尾部的地方,这种数据称为槽,页目录就是多个槽组成的。
·页内数据单向链表,页与页之间双向链表。
索引
·二级索引携带主键信息到聚簇索引重新定位完整记录的过程称为回表。
·二级索引记录的内容由三部分组成: ·索引列的值 ·主键值 ·页号
表空间
·表空间被划分为许多连续的区,对于16KB的页来说,连续的64个页就是一个区,也就是说一个区默认1MB。每256个区又被划分为一个组。
·一个索引会生成2个段,一个叶子节点段和一个非叶子节点段。
表连接的原理
·两个表的连接查询中,驱动表只需要访问一次,被驱动表可能需要访问多次。
成本优化
·读取一个页面花费成本默认1.0;读取及检测一条索引是否符合搜索条件的成本默认是0.2。这些称之为成本常数。
·在真正执行一条单表查询语句前,优化器会找出所有可以用来执行该语句的方案,并对比后找出成本最低的方案。
·查询成本 = I/O成本 + CPU成本
计算全表扫描的代价:
·聚簇索引占用的页面数
·该表中的记录数
通过show table status语句查询表的统计信息。
rows:表中的记录数,myisam是准确值,innodb是一个估值。
data_length:表占用的存储空间的字节数。 data_length = 聚簇索引的页面数量 X 每个页面的大小,默认页面大小为16KB。
假如一个表rows为9693; 假如data_length为1589248,则页面数量 = 1589248 / 16 /1024 = 97 。
则I/O成本:97*1.0+1.1 =98.1 CPU成本:9693*0.2+1.0 =1939.6 总成本 98.1+1939.6=2037.7
·多条索引的时候,查询优化器先分析使用唯一二级索引的成本。
使用二级索引+回表方式执行的查询
计算查询成本的时候依赖两方面数据:扫描区间数量+需要回表的记录数。
·扫描区间数量:读取一个扫描区间的I/O成本与读取一个页面的I/O成本相同。
·回表记录数:就是上述扫描区间中能扫描出来的二级索引的记录数。
比如有一个扫描区间(10,1000),计算过程:先找到>10的第一条记录,再找到满足<1000的最后一条记录,如果这2条记录相隔不远(不大于10个页面),则能精确计算出满足的条数,如果超过10个页面,则只沿着最左记录向右读取10个页面,计算平均一个页面有多少记录,然后乘以页面数量预估有多少记录。(要预估最左最右隔着多少页面,需要查找上一级索引看他们对应的索引页隔着多少记录即可)
·找到了这些记录条数还需要回表,默认以为回表操作相当于访问一个页面,所以有多少记录,就要回多少次表。
·回表找到完整记录后,还需要检测其他搜索条件是否成立。
所以总成本:I/O成本: 1.0+95*1.0=96.0(扫描区间数量 + 预估的二级索引记录数(也就是回表记录数)) CPU成本:95*0.2+0.01+95*0.2=38.01(读取二级索引的成本+回表后检测其他条件是否成立的成本)
对应in操作,比如in (0,100,1000)