3

まず第一に、私は次のテーブル構造を持っています。

Table Document
  ## DocID ##  ## DocName## ## DuplicateID ##
      1              Doc1        null
      2              Doc2        null
      3              Doc3        null
      4              Doc4         1

Table FolderTree
  ## FolderID ##  ## MemberDocID ##
       1                1
       1                2
       1                3

私はインデックスを持っていますDocID, DuplicateID and MemberDocID and FolderID

私の質問はこれです:

SELECT d.* 
from Document d, FolderTree f 
WHERE (d.DocID = f.MemberDocID or d.DuplicateID = f.MemberDocID) and f.FolderID = 1 
GROUP BY d.DocID ;

したがって、基本的には、ID 1のフォルダーからすべてのドキュメントを取得し、テーブルから重複するドキュメントも取得します。group byは、ドキュメントが2回取得されないというレコードの一意性を維持するために使用されます。

このクエリは正常に機能していますが、大量のレコードでは速度が低下しています。これが説明の出力です。


| select type | table | type | possible_keys | key    | rows  |   extra         |

   simple        d     range   PRIMARY,...    PRIMARY   83168   Using temporary..
   simple        f     All     DuplicateIDInx Null      108787  Using join buffer

私が懸念しているのは、テーブルfがDuplicateIDのインデックスを使用していないことです。私の質問は、なぜそうなのかということです。誰かがこの問題について私に教えてもらえますか。Mysql5.xを使用していますありがとうございます:)

4

3 に答える 3

1

このバージョンを試してください:

SELECT d.* 
FROM Document d 
WHERE EXISTS
      ( SELECT *
        FROM FolderTree f 
        WHERE ( d.DocID = f.MemberDocID OR d.DuplicateID = f.MemberDocID )
          AND f.FolderID = 1 
      ) ;

そしてこれ(編集):

SELECT d.* 
FROM ( SELECT 1 AS FolderID
     ) AS Parameter
  CROSS JOIN 
     Document d 
WHERE EXISTS
      ( SELECT *
        FROM FolderTree f 
        WHERE f.MemberDocID = d.DocID
          AND f.FolderID = Parameter.FolderID
      ) 
   OR EXISTS
      ( SELECT *
        FROM FolderTree f 
        WHERE f.MemberDocID = d.DuplicateID
          AND f.FolderID = Parameter.FolderID
      ) ;

また、に複合(複合)インデックスを追加しFolderTree (FolderID, MemberDocID)ます。

のインデックスをまだ作成していない場合は、インデックスDocument (DuplicateID)も追加します。

追加の要件は、パラメーターを使用してストアドプロシージャにクエリを記述することで、おそらくより適切に解決できます。

于 2012-12-07T09:38:39.490 に答える
1

適切なインデックスがないようです。テーブルの構造とクエリについて詳しく教えてください。

  1. 「またはd.DuplicateID=f.MemberID」でクエリで使用されるf.MemberID列について
  2. Explainは、テーブルFolderTreeのDuplicateIDInxインデックス名を示しています。テーブルからの正確なインデックス定義について言及できますか。
于 2012-12-07T09:42:00.367 に答える
1

代わりにin句を使用し、groupbyの代わりにdistinctを使用できます。

SELECT distinct d.* 
from Document d
join FolderTree f on f.MemberDocID in (d.DocID, d.DuplicateID)
WHERE f.FolderID = 1

SQL Fiddleによると、結合を明示的にする以外は、これはあまり変わっていません。

duplicateidただし、変更した場合

update document
set duplicateid = docid
where duplicateid is null

duplicateidのみを選択します

SELECT distinct d.* 
from Document d
join FolderTree f on f.MemberDocID = d.DuplicateID
WHERE f.FolderID = 1

のインデックスを使用しますduplicateid

于 2012-12-07T09:43:17.897 に答える