パフォーマンスの面では、これらの相関するサブクエリはあなたの昼食を食べることができます。また、MySQLがそれらを処理する方法のために、大規模なセットの場合はランチボックスもむさぼり食います。これらのサブクエリはそれぞれ、外部クエリで返されるすべての行に対して実行されます。そして、それは大きなセットでは非常に高価になる可能性があります。
別のアプローチは、インラインビューを使用してすべてのコンテンツの好き嫌いを具体化し、それに結合操作を実行することです。
ただし、このアプローチもコストがかかる可能性があります。特に、数十億行のうち、数行のコンテンツ行に対してのみ投票「カウント」が必要な場合はそうです。多くの場合、調べて返す必要のある行の数を制限するために、インラインビューに組み込むこともできる外部クエリからの述語があります。
そのインラインビューへのOUTER結合を使用したいので、クエリと同等の結果が返されます。 content
から行を返す vote
に一致する行がない場合 テーブル。
SELECT [... BUNCH OF FIELDS ...]
, COALESCE(v.likes,0) AS likes
, COALESCE(v.dislikes,0) AS dislikes
, COALESCE(v.myvote,'.Constants::NO_VOTE.') AS myvote
FROM content c
LEFT
JOIN ( SELECT vt.cId
, SUM(vt.vote = '.Constants::LIKE.') AS likes
, SUM(vt.vote = '.Constants::DISLIKE.') AS dislikes
, MAX(IF(vt.userId = '.USER_ID.',vt.vote,NULL)) AS myvote
FROM votes vt
GROUP
BY vt.cId
) v
ON v.cId = c.contentId
[... OTHER STUFF ... ]
インラインビュークエリ(別名v
)に注意してください )vote
のすべての単一行を確認します テーブル。サブセットのみが必要な場合は、適切な述語を追加することを検討してください(WHERE句で、または別のテーブルへのJOINとして)。 [... OTHER STUFF ...]
からの表示はありません クエリで、content
からほんの数行を返すかどうか または、likes
で並べ替えているために、すべての行が必要な場合 、など。
content
から選択された少数の行の場合 テーブルでは、(クエリのように)相関サブクエリを使用すると、実際には、巨大なインラインビューを実体化して、それに対して結合操作を実行するよりも高速になります。
ああ...そして両方のクエリについて、vote
の適切なインデックスは言うまでもありません cId
の先頭の列を持つテーブル パフォーマンスにメリットがあります。インラインビューの場合、MySQLのオーバーヘッドでfilesort
を実行する必要はありません。 GROUP BYを実行するために、これらすべての行を操作します。また、相関サブクエリの場合は、フルスキャンではなくインデックス範囲スキャンを使用する必要があります。