スキーマ:PostgreSQLがインデックスを正しく使用していないのはなぜですか?
create table records(
id varchar,
updated_at bigint
);
create index index1 on records (updated_at, id);
クエリ。最近更新されたレコードを繰り返し処理します。 10レコードを取得し、最後のレコードを覚えてから次の10レコードを取得します。
select * from objects
where updated_at > '1' or (updated_at = '1' and id > 'some-id')
order by updated_at, id
limit 10;
それはインデックスを使用していますが、それは賢明にそれを使用して、フィルタを適用すると、レコードのトンを処理していない、以下のクエリの説明でRows Removed by Filter: 31575
を参照してください。
or
を削除して左または右の状態のままにしておくと、奇妙なことです。これは両方でうまく動作します。しかし、両方の条件がor
と同時に使用される場合、インデックスを正しく適用する方法を理解できないかのようです。
Limit (cost=0.42..19.03 rows=20 width=1336) (actual time=542.475..542.501 rows=20 loops=1)
-> Index Scan using index1 on records (cost=0.42..426791.29 rows=458760 width=1336) (actual time=542.473..542.494 rows=20 loops=1)
Filter: ((updated_at > '1'::bigint) OR ((updated_at = '1'::bigint) AND ((id)::text > 'some-id'::text)))
Rows Removed by Filter: 31575
Planning time: 0.180 ms
Execution time: 542.532 ms
(6 rows)
Postgresのバージョンが9.6
'...どこupdated_atの> '1' ...'あなたは、整数リテラルを引用するべきではありません。 – wildplasser
@wildplasser引用符もなく、同じことを試しました。 –
'width = 1336'それは非常に広いテーブルです、 – wildplasser