2016-11-11 13 views
0

私は、複雑なクエリのインデックスをどのように構造化するかについて基本的な理解がないと思います。以下のクエリを考えると、テーブルPHOTOSの最適なインデックスは何ですか?私は、これは私にUsing index condition; Using temporary; Using filesortを与える現時点で私が持っている指標であり、このマルチジョインのマルチ条件クエリに対して作成する必要があるインデックスを作成するにはどうすればよいですか?

(...私は、私を信頼している)、それだけで 試行錯誤の多くを行うことなく、を知ることが可能であるべきであると感じ。可能であれば、一時的な/ filesortビットを取り除きたいと思います。

SELECT 
SQL_CALC_FOUND_ROWS 

PH.photoID 

FROM  PHOTOS    PH 
JOIN  PHOTO_TYPES   PT ON PT.photoTypeID  = PH.photoTypeID 
LEFT JOIN PHOTO_LINKS   PL ON PL.photoID   = PH.photoID 
LEFT JOIN PAYPAL_ITEMS   PI ON PI.photoID   = PH.photoID 
LEFT JOIN PHOTOGRAPHER_PRODUCTS PP ON PP.photographerID = PH.photographerID 

WHERE PH.shootID = 1234 

GROUP BY PH.photoID 

ORDER BY PH.timeAdded DESC 

LIMIT 0, 100; 

はEXPLAIN出力:

id select_type  table type possible_keys  key    key_len ref    rows filtered Extra 
1 SIMPLE   PH  ref  PRIMARY,testIndex testIndex  4 const    80632 100   Using index condition; Using temporary; Using filesort 
1 SIMPLE   PT  eq_ref PRIMARY    PRIMARY   1 PH.photoTypeID  1  100   Using index 
1 SIMPLE   PL  ref  photoID    photoID   4 PH.photoID   1  100   Using index 
1 SIMPLE   PCI  ref  photoID    photoID   5 PH.photoID,const 1  100   Using index 
1 SIMPLE   PP  ref  photographerID  photographerID 4 PH.photographerID 4  100   Using where; Using index 

testIndex: photoTypeID, photoID, photographerID, shootID, timeAdded 

そしてここでは、クエリは、(それが現実ではもっと複雑だが、私は最低限の関連PHOTOS -index関連のものにそれをストリップダウンしましたです

+0

インデックス/クエリをそのまま使用していることは間違いありませんか?あなたが定義した方法でtestIndexがPHテーブルで使用されることを消化するのは難しいようです。 – e4c5

+0

うん、ちょうど確認して確認! – Codemonkey

+0

pretty同じtestIndexがshootIdで始まらず、説明に 'const' – e4c5

答えて

0

in my indexing cookbookと記載されている複合体INDEX(shootID, photoID)が必要です。

  • shootIDWHERE=なので、
  • WHEREが処理されるすべて、私たちは...に移動することができますので
  • 、すなわちすべてのGROUP BYphotoID
  • 追加最初に来るしかし、我々は停止する必要がありますここではORDER BYGROUP BYと同じではないためです。

だから... ORDER BYLIMITは、tempとfilesortを必要とします。

しかし...別の問題があります(おそらく):JOINを実行すると、(通常)行数が膨らんでしまいます。 '明らかな'治療法は、GROUP BYを収縮させることです。しかし、任意の集計(およびSQL_CALC_FOUND_ROWS)は、膨らんだ値をカウントします。したがって、「問題」。

だから···JOINsを行うの前に、の前に数えてみましょう。ちょっと待って!なぜ結合したのですか?あなたはそれらから何かを取得していません。また、(ほとんど)LEFT JOINsであるため、フィルタリングにはJOINsを使用していません。

質問の意味を理解できませんが、かもしれないというヒントをお伝えします。

SELECT photoID 
    FROM 
    (
     SELECT SQL_CALC_FOUND_ROWS 
       photoID, photoTypeID, photographerID 
      FROM PHOTOS 
      WHERE shootID = 1234 
      ORDER BY PH.timeAdded DESC 
      LIMIT 0, 100 
    ) AS PH 
    JOIN PHOTO_TYPES PT ON PT.photoTypeID = PH.photoTypeID 
    LEFT JOIN PHOTO_LINKS PL ON PL.photoID = PH.photoID 
    LEFT JOIN PAYPAL_ITEMS PI ON PI.photoID = PH.photoID 
    LEFT JOIN PHOTOGRAPHER_PRODUCTS PP ON PP.photographerID = PH.photographerID 
    ORDER BY PH.timeAdded DESC; 

このバージョンにはINDEX(shootID, timeAdded)が必要です。それはあなたに正しい答えを与える、それはより速く、tmpまたはfilesortを使用しないでください。