xuzhenkang 发表于 2023-11-13 23:39

在MySQL中,使用B+树存储的索引CRUD执行效率如何?

如题。这里我们可以分析一下在数据库中,使用B+树做查询时,时间复杂度是怎样的。

---
先说结论。
综合看网上各种帖子,总结得出以下结论:
$O(m\log_mN)$、$O(\log_2m\log_mN)$、$O(\log_mN)$、$O(\log N)$
以上这些都是正确的。
从以下两个方面来做讨论。
1. 一般意义上的时间复杂度,仅考虑算法在计算上消耗的步骤,不考虑IO
        a. B+树搜索时间复杂度 = 搜索时访问的节点数量 * 节点的搜索时间复杂度
        b. 访问的节点数量 = B+树深度 =$\log_mN$
        c.   每个节点有m个数据,那么节点内的搜索时间复杂度:
        基于数组/链表的线性搜索 = $O(m)$
        基于数组的二分搜索 =$O(\log_2m)$
        d. 因此,B+树搜索时间复杂度 = $\log_mN \times O(m)$或者$\log_mN \times O(\log_2m)$,即$O(m\log_mN)$或$O(\log_2m\log_mN)$.
        e. 另外,$\log_2m\log_mN$可以继续化简,步骤如下:
       
        为什么可以设$m=2^x$,m在这里就是大于2的自然数,这句话其实就是问$2^x$能不能表示任意一个大于2的自然数。当然是可以的,因为$2^x$是一条大于0的连续曲线。    所以,在内存中,B+树在一个节点内也采用二分法查找元素(最快的方式了),B+树和二叉树的时间复杂度都是$O(\log_2{N})$,即在内存中(不考虑磁盘IO的特殊性),N叉树的查询时间复杂度都是$O(\log_2{N})$。
        > 然后,你就会发现,越想越对,上学的时候,数据结构的课程上,老师教过用二叉树表示多叉树,现在一想,确实如此。其实想想,多叉树中,在寻找多个叉的过程中,如果采用了二分查找,不就是二叉搜索树吗?相当于“多叉”的搜索,变成了子树,这棵子树是二叉搜索树了,所以时间复杂度是$O(\log_2{N})$就太正常了。
       
2. B+ 树主要用在数据库、文件系统上,对于这种使用场景,IO 最耗费时间,执行几条指令、多访问几个节点没关系,但是多几次 IO 那时间是疯狂上涨(机械磁盘寻道时间是ms级,如果访问一个数据就要一次IO,那 B+ 树的搜索时间就直接炸了),B+树为什么要设计成矮胖的形状?为什么非叶子节点不存数据?都是为了减少IO次数。所以**在实际工程中,我们讨论B+树的搜索时间复杂度,其实讨论的是磁盘 IO 次数。**那么,磁盘IO次数怎么计算呢,它和B+树的 m和N 有什么关系?
        - 因为
                - B+树的节点,即非叶子节点大小 = 页大小
                - 读取一页需要一次IO
               
- 所以
    - B+树的搜索过程中的IO次数 = 搜索过程中访问节点的数量 = B+树的深度 = $O(\log_mN)$

xiliang 发表于 2023-11-14 06:31

FruitBaby 发表于 2023-11-14 07:48

树结果的时间复杂度是OlogN,肯定在这个范围内

emailsina 发表于 2023-11-14 08:45

不明觉厉

Suber 发表于 2023-11-14 08:48

先点个赞再说!{:1_921:}{:1_921:}{:1_921:}

pjy612 发表于 2023-11-14 09:07

{:301_999:} 然而 学渣没看懂...

NAXLCQ 发表于 2023-11-14 09:49

学习了没懂慢慢理解吧

xuzhenkang 发表于 2023-11-14 12:20

pjy612 发表于 2023-11-14 09:07
然而 学渣没看懂...

哪里没懂呢?我可以单独补充些内容。

xuzhenkang 发表于 2023-11-14 12:21

NAXLCQ 发表于 2023-11-14 09:49
学习了没懂慢慢理解吧

哪里没懂呢?我可以写的再详细些

NAXLCQ 发表于 2023-11-14 23:02

xuzhenkang 发表于 2023-11-14 12:21
哪里没懂呢?我可以写的再详细些

已经很详细了 我慢慢参悟吧感谢感谢
页: [1] 2
查看完整版本: 在MySQL中,使用B+树存储的索引CRUD执行效率如何?