InnoDB的唯一二级索引非叶子节点存储了主键的值,这是为什么呢?

官方其实对这个问题有过详细的解答,可以看这里的链接:https://bugs.mysql.com/bug.php?id=68546
总结下来主要是下面两点:

  1. 因为在MySQL语义中,NULL != NULL为false, 所以,唯一二级索引可以为NULL,也就导致这种情况下可能会出现重复值,比如:

    CREATE TABLE t1 (a INT, b INT, c INT, d INT,
     PRIMARY KEY(a,b,c),
     UNIQUE KEY (a,d)) ENGINE=InnoDB;
    INSERT INTO t1 VALUES(1,1,1,NULL),(1,1,2,NULL),...,(1,1,99999,NULL);
    

    是合法的, PRIMARY KEY是不允许为NULL的。

    这个时候,假设btr_pcur_t::m_old_rec指向 (1,NULL,1,330)btr_pcur_restore_position函数就可以简单的解引用该节点,直接定位到所需的页面上, 但是,如果二级索引的叶子节点只存储(a,d,page_no),那么,就需要扫描所有的叶子节点挨个去查找目标page(因为有很多重复的),这样子性能会非常低下。

  2. 那么,是不是意味着这种优化就适用于唯一非NULL二级索引呢?其实也不是的,在MySQL中,支持MVCC的方式是通过undo来实现的,这个时候,如果有个事务update/delete了某一个tuple,由于MySQL是实现的delete-marker,后续由purge进行真正的删除动作,在二级索引(1,1,page_no)里,将会存储着多个page_nobtr_pcur_restore_position就得挨个进行遍历,性能同样也是非常低下的。

posted @ 2023-03-15 21:26  不晓得叫什么  阅读(50)  评论(1编辑  收藏  举报