次の表とインデックスを定義しています。
_CREATE TABLE IF NOT EXISTS data (
id serial,
job_id bigint NOT NULL,
payload jsonb NOT NULL,
tags jsonb NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_data_content on data (md5(payload::text));
CREATE INDEX IF NOT EXISTS idx_data_tags ON data USING GIN (tags jsonb_path_ops);
CREATE INDEX IF NOT EXISTS idx_data_jid ON data USING btree (job_id);
_
そのテーブルには、_job_id
_(_payload->>'jobId'
_でも使用可能)および_payload->>'__time'
_に格納されているタイムスタンプ(UNIXエポック)に関連付けられている多くのJSON BLOBを格納しています。重複するJSONブロブの保存を避けたいので、_ このメソッド をUNIQUE
制約として使用しています。ただし、DBで数十万行を超えると、INSERT
パフォーマンスが低下し始めます。これは、UNIQUE
制約なしでは起こりません。
ほとんどありませんが、same_job_id
_と_payload->>'__time'
_。たとえば、最初に_job_id
_をチェックし、次に_payload->>'__time'
_をチェックするUNIQUE
制約を定義して、両方が実際にmd5(payload::text)
インデックス?
(JSON BLOBのキーは、同じドキュメントに対して常に同じ順序であることに注意してください。)
一意性制約だけが問題である場合(そして、上記の説明で理由を詳しく知りたい場合)、ここにアイデアがあります。
order by id asc limit 1
重複を無視するここにいくつかのアイデアがあります。
関数の制約チェックを行います。
2番目はテーブルを変更し、欠落データを追加するトリガーを作成し、チェックする必要がある3つのフィールドに新しいインデックスを作成します
CREATE TRIGGER check_jsonb
BEFORE INSERT
ON data
FOR EACH ROW
EXECUTE PROCEDURE
CREATE FUNCTION public._check_jsonb()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
AS $BODY$
declare
_check_rec record;
begin
select job_id, payload from data where job_id = new.job_id
if found then
if _check.payload.__time == new.jsonb.__time
--do not know json command in postgresql
-- that well to extract this value
select true from data where new.payload == (md5(payload::text))
end if;
end if ;
return new;
$BODY$
-試す2番目のアイデア
CREATE TABLE IF NOT EXISTS data (
id serial,
job_id bigint NOT NULL,
payload jsonb NOT NULL,
tags jsonb NULL,
hash_check text not null,
time timestamp not null
);
create unique index if not exists idx_jobid_time on data (id, time, hash_check);
CREATE INDEX IF NOT EXISTS idx_data_tags ON data USING GIN (tags jsonb_path_ops);
CREATE INDEX IF NOT EXISTS idx_data_jid ON data USING btree (job_id);
CREATE TRIGGER check_jsonb_idea2
BEFORE INSERT or Update
ON data
FOR EACH ROW
EXECUTE PROCEDURE
CREATE FUNCTION public._check_jsonb_idea2()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
AS $BODY$
begin
new.time = new.jsonb.__time ;-- do not know json commands very while extract this
new.hash_check = (md5(payload::text))
return new;
end;
$BODY$
これにより、他のインデックスを削除することもできます