2017-06-19 9 views
0

私は、特定のユーザーによってまだランクされていない "Images"テーブル内のすべての行を取得するSELECTをmySQL(およびPHP)に書き込もうとしています。MySQL Seb-Selectへの変換方法

表:画像

+-----------+----------+-----------+----------+------------+ 
| Index  | Rank_Good| Rank_OK | Rank_Bad | Is_Allowed | 
+-----------+----------+-----------+----------+------------+ 
| 201  | 2  | 9   | 28  | true  | 
| 202  | 11  | 20  | 39  | false  | 
| 203  | 36  | 14  | 7  | true  | 
+-----------+----------+-----------+----------+------------+ 

表2:WhoAlreadyClickedImg(索引を持たない)

+------------+-----------------+-----------+ 
| ImageIndex | UserWhoRankedIt | RankGiven | 
+------------+-----------------+-----------+ 
| 202  | 87    | OK  | 
+------------+-----------------+-----------+ 
| 202  | 93    | Bad  | 
+------------+-----------------+-----------+ 
| 204  | 93    | Good  | 
+------------+-----------------+-----------+ 
| 203  | 94    | Bad  | 
+------------+-----------------+-----------+ 

私のロジック: ユーザーが画像をランク付けされ、

それらは私のテーブルです「WhoAlreadyClickedImg」テーブルに、ランク付けしたユーザーのIDとイメージID(およびランク)の行を追加します。 (これにより、このテーブルの各イメージごとに何千もの行が作成されます)

次に、ユーザーがイメージのランクを付けたい場合、「WhoAlreadyClickedImg」テーブルを調べて、彼がランク付けし、 "Images"テーブルからImages.Is_Allowedパラメータをクエリに追加します(私は彼にランク付けできるイメージのみを表示します)。

最初に私はサブセレクトでそれを行いましたが、それはチェックするすべての行に対してサブセレクトを呼び出し、非常に遅いです。 ( - 左が参加/インナーまたは右にそれをやったことがないと最高がどうなるかに精通していない)

答えて

1
SELECT Images.Index 
FROM Images 
LEFT JOIN WhoAlreadyClickedImg 
    ON WhoAlreadyClickedImg.ImageIndex = Images.Index 
    AND WhoAlreadyClickedImg.UserWhoRankedIt = 93 
WHERE Images.Is_Allowed = 1 
AND WhoAlreadyClickedImg.ImageIndex IS NULL 
ORDER BY RAND() 
LIMIT 1 

それを行う必要があることを

SELECT Images.Index 
FROM Images 
WHERE Images.Index NOT IN 
     (
      SELECT WhoAlreadyClickedImg.ImageIndex 
       FROM WhoAlreadyClickedImg 
       WHERE WhoAlreadyClickedImg.UserWhoRankedIt = 93 
     ); 
AND Images.Is_Allowed = 1 
ORDER BY RAND() 
LIMIT 1 

は、私がどのようにそれを登録しようとするべき見当がつかない。そのテーブルで左結合を行い、これらの条件に基づいてテーブルに対応する値がない場合、行はNULLとして戻され、WHERE節でこの条件をチェックできます。

テーブルが適切にインデックス化されていれば、両方のクエリに実際の違いはないはずです.MySQLは適切な計画を立てるのに十分にスマートでなければなりません。

+0

"WhoAlreadyClickedMyImg"テーブルにインデックスを追加しても、クエリでそれを無視しても、速度が向上しますか?どうやって?! – marble

+0

「あなたはそれを完全に無視する」とはどういう意味ですか? –

+0

私は今、 "WhoAlreadyClickedMyImg"テーブルにIndex colがないことを意味します。 (なぜなら、クエリが機能するために必要なのではないからです)。だから私のクエリでそれを使用していない場合でも、私はそのテーブル内のインデックスの列を作成する必要がありますか? – marble

関連する問題