-1

イベントがあります。イベントは非公開にすることができます - 招待されたユーザーのみがそのイベントを見ることができます, パブリック - すべての人が見ることができます, グループ内 - グループのメンバーだけが見ることができます. グループは公開または非公開にすることができます。プライベート グループのイベントは表示しないでください。

event
id, title, group (nullable), is_private

event_invitee
event_id, user_id

group
id, title, is_open

group_participant
group_id, user_id

したがって、現在認証されているユーザーが利用できるイベントを表示するために、(疑似コード) のようなクエリを実行します。

SELECT
  e
FROM event e
  LEFT JOIN e.invitees i WITH i.user = :current_user # is current user invited to event ?
  LEFT JOIN e.group g
  LEFT JOIN g.participants p WITH g.user = :current_user # is current user are participant of group?
WHERE ((e.group IS NULL OR g.is_open = true OR (g.is_open = false AND p IS NOT NULL))
  AND (r.is_private = false OR (r.is_private = true AND i IS NOT NULL)))
  AND /* other filters, like by location */

これはうまく機能しますが、非常に遅いです。そして、それが古くなる可能性はありません。結果をより迅速かつスケーラブルに取得するために構造を変更するにはどうすればよいでしょうか?

4

1 に答える 1

-1

処理を高速化するには、「左結合」を「where句」に書き直す必要があります。これは、口で言うほど簡単ではありません。ただし、ほとんどのレコードを最初にドロップするフィルターを適用するという利点があります。1つの場所にイベントが10個しかなく、場所フィルターが選択されている場合、クエリはその場所にないプライベート、パブリック、またはグループのイベントをフィルターする必要はありません。これは簡単だと言っているのは知っていますが、データがなければ実際のコードを提示することはできません。これがあなたを正しい方向に向けさせてくれたことを願っています。30秒以上続くクエリを1秒強にスピードアップすることができました。結局、本番データベースのインデックスをスクリプト化するのを忘れていたことがわかりました。したがって、適切に配置されたインデックスを追加して、処理を高速化することもできます。

于 2012-10-12T14:08:36.150 に答える