2013-08-21 48 views
-1

可以说我有4桌'A(id, type, protocol), B(id, A_id, info), C(id, B_id, details) and D(id, C_id, port_info)。表A和表B通过来自表A的外键id和来自表BA_id连接。类似地,表B和表C经由外键id从表BB_id从表C连接,并且以相同的方式,表C和表D也被连接。如何使嵌套查询更高效?

现在,我想从表A的所有protocols的表D得到port_info。 我知道一种方法,其时间复杂度为O(n^4),目前我正在使用它。该方法如下:

db = MySQLdb.connect(host="localhost", user="root", passwd="", db="mydb") 
cur = db.cursor() 
cur.execute("SELECT * FROM A") 

A_results = cur.fetchall() 
for A_row in A_results : 
    id  = A_row[0] 
    cur.execute("SELECT * FROM B WHERE A_id = %d " % (id)) 
    B_results = cur.fetchall() 

    for B_row in B_results : 
     id  = B_row[0] 
     cur.execute("SELECT * FROM C WHERE B_id = %d " % (id)) 
     c_results = cur.fetchall() 

     for C_row in C_results : 
      id  = C_row[0] 
      cur.execute("SELECT * FROM D WHERE C_id = %d " % (id)) 
      D_results = cur.fetchall() 

      for D_row in D_results : 
       print "Port = " + str(port) 

但这种方法需要O(n^4),所以有在time complexity方面的任何有效的方法,可以解决这个问题。

您的建议非常感谢。

+0

MySQL(或甚至任何SQL)101.请参阅JOIN。 – Strawberry

回答

2

在单个JOIN查询中执行它,让MySQL在处理大型数据集(毕竟这是数据库最好的)时进行必要的优化,为应用程序提供单个结果集。查询看起来是这样的:

SELECT A.protocol, D.port_info 
FROM A JOIN B ON A.id = B.A_id 
     JOIN C ON B.id = C.B_id 
     JOIN D ON C.id = D.C_id 
ORDER BY protocol 

...然后用你的光标来检查单个结果集。

+0

这将会是什么时间复杂? – PythonEnthusiast

+0

O(n)(在Python级别),因为您使用一个循环而不是四个返回的结果集。如果这个问题是出于学术目的,你可能也想考虑MySQL的内部处理这些连接以及B树如何工作。如果它不是为了学术目的,而是为了实际工作,那么大O符号就远不如对DB的嵌套I/O操作的惩罚那么重要。 –

+0

换句话说,你的意思是说我不应该在实时工作时使用JOIN操作? – PythonEnthusiast