数据库端的昂贵查询

时间:2015-05-29 09:52:14

标签: sql rdbms

让我们考虑这两个表:

|     Person    |
----------------
|  ID  | Name   | 
_________________
|  1   |  alice |
|  2   |  bob   |  
|  ... |  ...   |  
| 99   |  zach  |  


| PersonFriend  |
----------------
|  ID  |FriendID| 
_________________
|  1   |  2     |
|  2   |  1     |  
|  2   |  99    |
| ...  |  ...   |  
| 99   |  1     |  

这是两个表格来模仿朋友和朋友的朋友。 现在第一个查询是:
1) Bob的朋友是谁?
使用SQL的查询是:

SELECT p1.Person
FROM Person p1 JOIN PersonFriend  ON PersonFriend.FriendID = p1.ID 
     JOIN Person p2  ON PersonFriend.PersonID = p2.ID 
WHERE p2.Person = 'bob'

现在考虑反之亦然:
2)谁是Bob的朋友?
SQL中的查询是:

SELECT p1.Person 
FROM Person p1 JOIN PersonFriend  ON PersonFriend.PersonID = p1.ID 
     JOIN Person p2  ON PersonFriend.FriendID = p2.ID 
WHERE p2.Person = 'bob' 

嗯,这两个查询都很简单,但我不明白为什么第二个查询在数据库方面比第一个查询更昂贵。有人能帮助我吗?

2 个答案:

答案 0 :(得分:0)

我记得在Neo4j图表数据库书中引用了这个例子,并认为这是一个非常人为的例子。在上面提到的例子中,没有性能损失。

正如他们在本书后面解释的那样,只有朋友之类的更复杂的查询计算成本很高。

实施例2-3。爱丽丝的朋友朋友

SELECT p1.Person AS PERSON, p2.Person AS FRIEND_OF_FRIEND
FROM PersonFriend pf1 JOIN Person p1
ON pf1.PersonID = p1.ID
JOIN PersonFriend pf2
ON pf2.PersonID = pf1.FriendID
JOIN Person p2
ON pf2.FriendID = p2.ID
WHERE p1.Person = 'Alice' AND pf2.FriendID <> p1.ID

答案 1 :(得分:0)

我尝试自己回复。 让我们考虑两个查询的查询树:

1)Bob的朋友是谁?

   PROJ p1.Person
          |
          |
     J   O   I   N 
 p1.ID=PersonFriend.FriendID 
     /            \
    /              \
   /                \
Person p1    ###### J   O   I   N ######
              p2.ID=PersonFriend.PersonID 
                      /         \
                     /           \ 
                    /             \ 
                SEL(Persona p2)   PersonFriend
           p2.Person="bob"

2)谁是鲍勃的朋友?

     PROJ p1.Person
              |
              |
         J   O   I   N 
     p1.ID=PersonFriend.PersonID 
         /            \
        /              \
       /                \
    Person p1    ###### J   O   I   N ######
                  p2.ID=PersonFriend.FriendID  
                          /         \
                         /           \ 
                        /             \ 
                    SEL(Persona p2)   PersonFriend
               p2.Person="bob"

PersonFriend表的键是复合:,记录按ID排序。 正如您所看到的,由哈希标记的两个连接具有不同的参数。第一个不需要迭代PersonFriend表的所有记录,因为记录按ID排序。第二个连接需要迭代PersonFriend表的所有记录  我认为这就是为什么第二个查询比第一个查询更昂贵的原因。