2013-08-21 87 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