0

以下のクエリを最適化するのに助けが必要です。写真の各投票 (-1 または 1) を保持する 30+k レコードを持つテーブル pt_votes があり、すべての写真とその投票合計を選択したいので、以下のようなクエリがありますが、実行に約 9 秒かかります。どうすれば最適化できますか?

 SELECT *, ifnull((SELECT SUM(vote) FROM pt_votes vo WHERE vo.pID = ph.pID),0) points,
                        (SELECT CONCAT(name, " ", surname) FROM pt_users us WHERE us.uID = ph.uID) name_surname
                    FROM pt_photos ph
                    WHERE 1
4

5 に答える 5

0

まったくテストされていませんが、これが役立つかどうか試してみてください

SELECT *, SUM(ifnull(vo.vote,0)) points, CONCAT(us.name, " ", us.surname) name_surname
FROM pt_photos ph
LEFT JOIN pt_votes vo ON vo.pID = ph.pID
JOIN pt_users us ON us.uID = ph.uID
于 2013-07-26T18:45:46.423 に答える
0

3 番目の選択を内部結合として書き直して、結果を出力するときに concat 関数を移動することをお勧めします。これは t-sql ソリューションですが、十分に似ているはずです。

select ph.*, 
concat(pu.name, " ", pu.surname) as name_surname,
isnull((select sum(vote) from pt_votes vo where vo.pid = ph.pid),0) as points
from pt_photos ph
inner join pt_users pu on ph.uid = pu.uid

合計のために pt_votes テーブルへの左結合を行うこともできますが、それをすべて機能させるには「group by」句をいじる必要があり、処理時間のために価値があるかもしれません。

于 2013-07-26T18:53:30.730 に答える
0

相関サブクエリではなく、JOIN を使用します。

SELECT ph.*,
       IFNULL(SUM(vo.vote), 0) points,
       CONCAT(us.name, " ", us.surname) name_surname
FROM photos ph
LEFT JOIN pt_votes vo ON ph.pId = vo.pID
INNER JOIN pt_users us ON us.uID = ph.uID
GROUP BY ph.uID

私の知る限り、WHERE 1すべての行を選択する句は必要ありません。WHERE句を省略してください。

于 2013-07-26T18:47:19.437 に答える
0

Correlated subqueries make for light dimming queries on large sets, due to the number of times that subquery is executed.

Here's an alternative that should perform better:

SELECT ph.*
     , IFNULL(vs.points,0) AS points
     , CONCAT(us.name," ",us.surname) AS name_surname
  FROM pt_photos ph
  LEFT
  JOIN ( SELECT vo.pID
              , SUM(vo.vote) AS points
           FROM pt_votes vo
          GROUP BY vo.pID
       ) vs
    ON vs.pID = ph.pID
  LEFT
  JOIN pt_users us 
    ON us.uID = ph.uID
 WHERE 1

A suitable index (ideally a covering index) on pt_votes will improve performance of the GROUP BY... on pt_votes (pID, vote).

I'm going to assume that uID is the pirmary key of pt_users.

于 2013-07-26T18:48:45.337 に答える