0

event_datetime 列と event_duration_minutes 列を含む既存の「イベント」テーブルがあります。2 つの列は、それぞれ日時と整数です。

最近、イベントの終了時にメールをトリガーする必要があることに気づきました。これを達成するために、最近完了したイベントを探して 10 分ごとに DB を一掃する定期的なジョブを作成しています。そこで、特定の時間枠内に終了したすべてのイベントを検索するクエリの作成を開始しましたが、各レコードの期間フィールドの可変性により、クエリを実行できませんでした。

end_time 列を追加し、自動的に start_time + duration に設定するのが最善の方法だと考えています。それは正しい方法ですか?

いずれにせよ、クエリの実行方法について完全な空白を描いています-これらのケースにアプローチする簡単な方法はありますか? または、そのようなクエリの一般的な必要性は、DB に何らかの作業が必要であることを示していますか?

編集 - これはpostgres 9.2にあります。Rails schema.rb のスキーマは次のようになります。

create_table "events", :force => true do |t|
  t.string   "title"
  t.text     "details"
  t.datetime "created_at",             :null => false
  t.datetime "updated_at",             :null => false
  t.datetime "event_datetime"
  t.integer  "instructor_id"
  t.integer  "event_duration_minutes"
  t.datetime "started_at_time"
end
4

1 に答える 1

2

これに対する通常の解決策は、計算された終了時間に式インデックスを作成することです。その後、インデックス検索を簡単に実行できます。

これを行う最も簡単な方法は、計算を行う単純な SQL 関数を定義し、それを式インデックスとインデックスを使用するクエリの両方で使用することです。

例えば:

CREATE OR REPLACE FUNCTION startduration_to_end(starttime timestamp, duration_minutes integer) RETURNS timestamp AS $$
SELECT $1 + $2 * INTERVAL '1' MINUTE';
$$ LANGUAGE sql;

それから:

CREATE INDEX mytable_end_index ON mytable 
( (startduration_to_end(event_datetime,event_duration_minutes ) );

クエリのパターンによっては、開始時間と終了時に別のものが必要になる場合がありますが、テーブルの変更率が高い場合は、インデックスを維持するコストを念頭に置いてください。

CREATE INDEX mytable_end_index ON mytable 
(event_datetime, (startduration_to_end(event_datetime,event_duration_minutes ) );

startduration_to_end関数を使用して、これらのインデックスを使用してクエリを実行できます。

SELECT *
FROM mytable t
WHERE startduration_to_end(t.event_datetime,t.event_duration_minutes) BETWEEN current_timestamp - INTERVAL '10' MINUTE AND current_timestamp;

実行時間の変動などにより、実際には、検索が重複する十分な数のインデックスをスキャンするか、最後の 10 分間ではなく、最後の検索の正確なタイムスタンプよりも新しいものをすべて検索する必要があります。

于 2013-05-13T03:30:12.247 に答える