ほぼ200万行のコメントを含むテーブルがあります。1日あたり約500件の新しいコメントを受け取ります。各コメントは特定のIDに割り当てられます。特定のIDに基づいて最も人気のある「ディスカッション」を取得したいと思います。
ID列にインデックスがあります。
ベストプラクティスは何ですか?このIDでグループ化してから、コメントが最も多いIDで並べ替えますか?これは、このサイズのテーブルにとって最も効率的ですか?
ほぼ200万行のコメントを含むテーブルがあります。1日あたり約500件の新しいコメントを受け取ります。各コメントは特定のIDに割り当てられます。特定のIDに基づいて最も人気のある「ディスカッション」を取得したいと思います。
ID列にインデックスがあります。
ベストプラクティスは何ですか?このIDでグループ化してから、コメントが最も多いIDで並べ替えますか?これは、このサイズのテーブルにとって最も効率的ですか?
このIDでグループ化してから、コメントが最も多いIDで並べ替えますか?
それは私がそれをする方法とほとんど同じです。トップ50を取得したいとします。
SELECT id
FROM comments
GROUP BY id
ORDER BY COUNT(1) DESC
LIMIT 50
ユーザーがアプリケーションでこのクエリを頻繁に実行していて、希望する速度で実行されていないことがわかった場合、最適化する1つの方法は、上記のクエリの結果を別のテーブルに保存することです(topdiscussions
)、おそらく5分ごとに断続的に実行されるスクリプトまたはcronがあり、そのテーブルが更新されます。
次に、アプリケーションで、ユーザーにテーブルから選択してもらい、 200万行ではなく50topdiscussions
行から選択するだけで済みます。
もちろん、これの欠点は、選択がリアルタイムではなく、最大5分ずれているか、テーブルを更新したい場合があることです。実際にどの程度リアルタイムである必要があるかは、システムの要件によって異なります。
編集:この回答に対するあなたのコメントによると、私はあなたのスキーマと要件についてもう少し知っています。次のクエリは、過去1日以内に最も活発なディスカッションを取得します。
SELECT a.id, etc...
FROM discussions a
INNER JOIN comments b ON
a.id = b.discussion_id AND
b.date_posted > NOW() - INTERVAL 1 DAY
GROUP BY a.id
ORDER BY COUNT(1) DESC
LIMIT 50
あなたのフィールド名はわかりませんが、それが一般的な考え方です。
あなたの質問を理解した場合、IDはコメントが添付されているディスカッションを示します。したがって、最初に最も人気のある概念が必要になります。
1)IDでコメントをカウントし、「delta」という列を0に設定して、「コメント合計」テーブルを初期化します。
2)定期的に
2.1)IDでコメントを数える
2.2)新しいカウントから古いカウントを減算し、その値をデルタ列に格納します。
2.3)コメントの数を新しい数に置き換えます。
3)デルタの降順でコメント合計から10行を選択して、10個の「最もホットな」ディスカッションを選択します。
今、残りは取るに足らないです。これは、ディスカッションIDが手順3で見つけたものと一致するコメントにすぎません。