2012-12-05 96 views
0

我有一個很長的查詢是切換資源,並需要重寫它。 它的一個顯而易見的問題是在where子句中使用「not in」。 我最初的想法是重寫它,廢除所有的自聯接,並在子查詢上做一個「不存在」。有沒有想過這樣做,或者比這更有效的想法?一個更好的方法來寫這個MySQL選擇查詢

這裏的查詢:

SELECT a.referenceid, 
     a.memberid AS d1, 
     b.memberid AS d2, 
     c.memberid AS d3, 
     d.memberid AS d4, 
     e.memberid AS d5, 
     f.memberid AS d6 
FROM jos_comprofiler_members AS a FORCE INDEX (aprm) 
     LEFT JOIN jos_comprofiler_members AS b FORCE INDEX (aprm) 
       ON a.memberid = b.referenceid 
       AND b.accepted = 1 
       AND b.pending = 0 
     LEFT JOIN jos_comprofiler_members AS c FORCE INDEX (aprm) 
       ON b.memberid = c.referenceid 
       AND c.accepted = 1 
       AND c.pending = 0 
     LEFT JOIN jos_comprofiler_members AS d FORCE INDEX (pamr) 
       ON c.memberid = d.referenceid 
       AND d.accepted = 1 
       AND d.pending = 0 
     LEFT JOIN jos_comprofiler_members AS e FORCE INDEX (pamr) 
       ON d.memberid = e.referenceid 
       AND e.accepted = 1 
       AND e.pending = 0 
     LEFT JOIN jos_comprofiler_members AS f FORCE INDEX (pamr) 
       ON e.memberid = f.referenceid 
       AND f.accepted = 1 
       AND f.pending = 0 
WHERE a.referenceid = 1593 
     AND a.accepted = 1 
     AND a.pending = 0 
     AND f.memberid = 1593 
     AND b.memberid NOT IN (1593, a.memberid) 
     AND c.memberid NOT IN (1593, a.memberid, b.memberid) 
     AND d.memberid NOT IN (1593, a.memberid, b.memberid, c.memberid) 
     AND e.memberid NOT IN (
      1593, a.memberid, b.memberid, c.memberid, d.memberid) 
     AND f.memberid NOT IN (1593, a.memberid, b.memberid, c.memberid, 
           d.memberid, e.memberid) 
LIMIT 0, 1 
+0

WOAH!這是很多... –

+0

對不起,我不清楚這些連接點是什麼.. – Kermit

+0

您正試圖從同一張表中獲得6個不同的成員ID?你能提供關於這個查詢目標的更多信息嗎? – Jeffrey

回答

0

您的查詢的1593反問的距離6內尋找所有成員:這個涉及到六度分離?

通常,在SQL中查找這樣的列表需要遞歸查詢或一些非SELECT構造(循環,遊標)。我不知道當列表由可變成員組成時,MySQL如何處理not in。但是,我懷疑它是爲每一個進行某種嵌套的循環連接。

建議:將not in聲明移至on條款。例如:

LEFT JOIN jos_comprofiler_members AS c FORCE INDEX (aprm) 
      ON b.memberid = c.referenceid 
      AND c.accepted = 1 
      AND c.pending = 0 
      AND (c.memberId <> b.MemberId an c.MemberId <> a.MemberId and c.MemberId <> 1593) 

這可以改善事情。或者讓它們變得更糟。但這是一個想法。

+0

感謝您的回覆戈登,我終於能夠確切地追蹤到查詢創建的位置,而您正確的,它是確定查看該配置文件的成員與配置文件擁有者之間的分離程度。我們不需要這個功能,所以暫時我只是將這個查詢從函數中註釋掉了。如果由於某種原因再次需要功能,它將不得不被重寫,但現在看起來不可思議的哈哈。我仍然不禁想知道如何改寫這種最好,最有效的方法。 –

+0

@SpencerFraise。 。 。如果您只查找一個成員,那麼最好的方法可能是將該成員加載到一個臨時表中,然後在while循環中一次迭代地添加成員,一次分離。 –

相關問題