综上所述,对于titles的全表扫描所需的总成本就是89666。
我们前边说过表中的记录其实都存储在聚簇索引对应B+树的叶子节点中,所以只要我们通过根节点获得了最
左边的叶子节点,就可以沿着叶子节点组成的双向链表把所有记录都查看一遍。也就是说全表扫描这个过程
其实有的B+树内节点是不需要访问的,但是MySQL在计算全表扫描成本时直接使用聚簇索引占用的页面数作
为计算I/O成本的依据,是不区分内节点和叶子节点的。
计算PRIMARY需要多少成本的关键问题是:需要预估预估出根据对应的where条件在主键索引B+树中存在多少条符
合条件的记录。
当我们从索引中查询记录时,不管是=、in、>、<这些操作都需要从索引中确定一个范围,不论这个范围区间的
索引到底占用了多少页面,查询优化器粗暴的认为读取索引的一个范围区间的I/O成本和读取一个页面是相同的。
本例中使用PRIMARY的范围区间只有一个:(10101, 20000),所以相当于访问这个范围区间的索引付出的I/O成本
就是:
1 x 1.0 = 1.0
优化器需要计算索引的某个范围区间到底包含多少条记录,对于本例来说就是要计算PRIMARY在(10101, 20000)
这个范围区间中包含多少条数据记录,计算过程是这样的:
步骤1:先根据emp_no > 10101这个条件访问一下PRIMARY对应的B+树索引,找到满足emp_no
> 10101这个条件的第一条记录,我们把这条记录称之为区间最左记录。
步骤2:然后再根据emp_no < 20000这个条件继续从PRIMARY对应的B+树索引中找出第一条满足
这个条件的记录,我们把这条记录称之为区间最右记录。
步骤3:如果区间最左记录和区间最右记录相隔不太远(只要相隔不大于10个页面即可),那就可
以精确统计出满足emp_no > '10101' and emp_no < '20000'条件的记录条数。否则只沿着区间最
左记录向右读10个页面,计算平均每个页面中包含多少记录,然后用这个平均值乘以区间最左记
录和区间最右记录之间的页面数量就可以了。那么问题又来了,怎么估计区间最左记录和区间最右
记录之间有多少个页面呢?计算它们父节点中对应的目录项记录之间隔着几条记录就可以了。
根据上面的步骤可以算出来PRIMARY索引的记录条数,所以读取记录的CPU成本为:26808*0.2=5361.6,其中
26808是预估的需要读取的数据记录条数,0.2是读取一条记录成本常数。
14p
W