0

リソースをザッピングしている長いクエリがあり、それを書き直す必要があります。これに関する明らかな問題は、where句での「notin」の使用です。私の最初の考えは、すべての自己結合を削除し、サブクエリで「存在しない」ことを実行して書き直すことです。それを行うことについて何か考えがありますか、それともそれよりも効率的なアイデアですか?

クエリは次のとおりです。

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  
4

1 に答える 1

0

あなたの質問は1593の距離6内のすべてのメンバーを探しています。修辞的な質問:これは6度の分離に関連していますか?

通常、SQLでこのようなリストを見つけるには、再帰クエリまたは非SELECT構造(ループ、カーソル)が必要です。not inリストが変数メンバーで構成されている場合、MySQLがをどのように処理するかわかりません。ただし、それぞれに対して何らかのネストされたループ結合を実行しているのではないかと思います。

提案: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)

これは物事を改善する可能性があります。またはそれらを悪化させます。しかし、それはアイデアです。

于 2012-12-05T20:23:57.110 に答える