sql join 算法 时间复杂度

参考

stackoverflow

笔记

sql语句如下:

SELECT  T1.name, T2.date
FROM    T1, T2
WHERE   T1.id=T2.id
        AND T1.color='red'
        AND T2.type='CAR'

假设T1有m行,T2有n行,那么,普通情况下,应该要遍历T1的每一行的id(m),然后在遍历T2(n)中找出T2.id = T1.id的行进行join。时间复杂度应该是O(m*n)

如果没有索引的话,engine会选择hash join或者merge join进行优化。

hash join是这样的:

  1. 选择被哈希的表,通常是小一点的表。让我们愉快地假定是T1更小吧。
  2. T1所有的记录都被遍历。如果记录符合color=’red’,这条记录就会进去哈希表,以id为key,以name为value。
  3. T2所有的记录被遍历。如果记录符合type=’CAR’,使用这条记录的id去搜索哈希表,所有命中的记录的name的值,都被返回,还带上了当前记录的date的值,这样就可以把两者join起来了。

时间复杂度O(n+m),实现hash表是O(n),hash表查找是O(m),直接将其相加。

merge join是这样的:

1.复制T1(id, name),根据id排序。
2.复制T2(id, date),根据id排序。
3.两个指针指向两个表的最小值。

    >1 2<
     2 3
     2 4
     3 5

4.在循环中比较指针,如果match,就返回记录。如果不match,指向较小值的指针指向下一个记录。

>1  2<  - 不match, 左指针小,左指针++
 2  3
 2  4
 3  5

 1  2<  - match, 返回记录,两个指针都++
>2  3
 2  4
 3  5

 1  2  - match, 返回记录,两个指针都++
 2  3< 
 2  4
>3  5

 1  2 - 左指针越界,查询结束。
 2  3
 2  4<
 3  5
>

时间复杂度O(n*log(n)+m*log(m))。排序算法的复杂度分别是O(n*log(n))和O(m*log(m)),直接将两者相加。

在这种情况下,使查询更加复杂反而可以加快速度,因为更少的行需要经受join-level的测试?

当然了。

如果原来的query没有where语句,如

SELECT  T1.name, T2.date
FROM    T1, T2

是更简单的,但是会返回更多的结果并运行更长的时间。

没有更多推荐了,返回首页