2

タイトルが少しでしたら申し訳ありません... くだらない。基本的に私は小さなフォーラムを書いており、複数のサブクエリを使用してスレッド数、投稿数、フォーラムの最後の投稿の日付を選択し、同時にフォーラムの情報を取得してメイン ページに表示しています。 !

私は物事を説明するのが苦手なので、これは私の質問です。

SELECT `f`.*,
    (SELECT COUNT(`id`)
    FROM `forum_threads` 
    WHERE `forumId1` = `f`.`id1`
        AND `forumId2` = `f`.`id2`) AS `threadCount`,
    (SELECT COUNT(`id`)
    FROM `forum_posts` 
    WHERE `forumId1` = `f`.`id1`
        AND `forumId2` = `f`.`id2`) AS `postCount`,
    (SELECT `date`
    FROM `forum_posts` 
    WHERE `forumId1` = `f`.`id1` 
        AND `forumId2` = `f`.`id2` 
        ORDER BY `date` DESC LIMIT 1) AS `lastPostDate`
FROM `forum_forums` AS `f`
ORDER BY `f`.`position` ASC, `f`.`id1` ASC;

そして、一般的な foreach ループを使用して結果を表示しています。

foreach($forums AS $forum) {
    echo $forum->name .'<br />';
    echo $forum->threadCount .'<br />';
    echo $forum->postCount .'<br />';
    echo $forum->lastPostDate .'<br />';
}

(もちろん、正確にはそうではありませんが、説明のために...)

それがパフォーマンスにとって「悪い」かどうか、またはそれを行うためのより良い方法があるかどうか疑問に思っていましたか? 各フォーラムにかなりの数の投稿とスレッドがあると仮定します。

私は元々、フォーラム テーブル自体に「投稿」、「スレッド」、および「lastPost」列を格納していましたが、誰かが新しいスレッドまたは投稿を作成するたびに値をインクリメント (投稿 = 投稿 + 1) しようとしていました。私もこの考えを持っていて、それが良いかどうか疑問に思っていました. :P

4

2 に答える 2

2

私は少し違うやり方をし

ます: これらの 3 つのフィールドはすべて:threadCountとは別のテーブルで維持できるフィールドでpostCountあり、 4 つの列のみを保持するとします: * forum_id * thread_count * post_count * last_post_datelastPostDateforum_stats




これらの列は、経由で更新できます。挿入/更新時にトリガーします。
更新操作中にこの小さなオーバーヘッドを支払うと、非常に高速なクエリが得られますselect(フォーラム/投稿/スレッドの数に関係なく、非常に高速なままです)。

別のアプローチ (TMO としては適切ではありません):統計テーブルを作成し、統計を更新するバッチ ジョブ
を 毎日 (または数時間ごとに) 実行します。価格は、表示するデータが最新のものではないことと、ジョブがリソースを必要とする可能性があることです。たとえば、負荷が高く影響を与えたくないため、夜間にのみジョブを実行することをお勧めします。あなたのウェブサイト訪問者の大半。

于 2012-08-29T05:52:42.363 に答える
1

通常、この種のことはパフォーマンスの観点からはひどいものであり、単一の行からフェッチできるカウンター列を使用する方がよいでしょう。これらの同期を維持するのは煩わしい場合がありますが、一度同期すれば取得コストはかかりません。

取得するデータを特定したので、次に行う必要があるのは、最初にそのデータをそこに配置する方法を理解することです。@alfasinの回答はスキーマの例を説明しており、それを別のテーブルに入れることは1つのアイデアですが、通常、それらをメインのテーブルに入れるだけで問題が発生することはあまりありません。ロックが心配な場合は、小さなバッチで更新してください。

1 つの方法はTRIGGER、さまざまなテーブルでレコードが追加および削除されるときにカウンターを更新する を作成することです。これは複雑さの多くを隠す傾向があり、ロジックが頻繁に変更され、システムがどのように機能するかを人々が認識する必要がある場合、悪いことになる可能性があります.

簡単な方法は、列を更新するものを作成または削除した後で、追加のクエリを使用して列をいじることです。たとえば、投稿の作成時に最終投稿日を調整するのは簡単です。

これらのカウンターが少しおかしくなり、最終的にはそうなる場合は、それらを同期に戻す方法が必要です。簡単な方法はVIEW、クエリが現在行っているのと同じ結果を生成する a を作成し、おそらくLEFT JOIN代わりに使用するために書き直してから、UPDATE可能であればそれに対して作成することです。これには、MySQL がそれ自体のビューを持つテーブルの更新に対応できない場合に一時テーブルを使用することが含まれる場合がありますが、通常は大したことではありません。

于 2012-08-29T06:07:02.570 に答える