postgresql に 1,000 万行を超えるテーブルが 1 つあります。1 つのフィールドを更新したいと考えています。
update annonce set confirmed = true;
しかし、クエリの実行には時間がかかります。このクエリを最適化するにはどうすればよいですか?
postgresql に 1,000 万行を超えるテーブルが 1 つあります。1 つのフィールドを更新したいと考えています。
update annonce set confirmed = true;
しかし、クエリの実行には時間がかかります。このクエリを最適化するにはどうすればよいですか?
update annonce set confirmed = true
where not confirmed
部分インデックスは次の場合に役立ちます。
create index index_name on annonce (confirmed)
where not confirmed
完全なインデックスと比較して、部分的なインデックスはインデックスのサイズを大幅に削減し、すべての更新、削除、および挿入操作を高速化します。
頻繁に行う場合は、次のように少し変更する必要があります。
UPDATE announce
SET confirmed = TRUE
WHERE NOT confirmed
また、 にインデックスを作成する必要があります(confirmed)
。
今日、毎回テーブル全体を変更しているため、多くのデッド行が作成されます - 基本的にテーブルは肥大化しています。提案された方法を使用すると、新しいレコードに対して不要な行を作成するだけで、それにもインデックスが作成されます。非常に高速で効率的です。
ここまでで 3 つの答えが得られました。
それらはすべて間違っています。
それらのどれも考慮しませんNULL
。そして、ここで考慮する必要NULL
があるのは唯一のものです! あなたがコメントで明らかにしたように:
「確認済み」は今追加したテーブルのフィールドです
すべての行にはconfirmed IS NULL
定義があります。WHERE
条項はまったく役に立ちません。少し費用がかかります。
元の質問には含まれていなかったため、列を追加したことを知らなかったとしてNULL
も、除外されていないため、ステートメントは次のようにする必要があります。
UPDATE announce
SET confirmed = TRUE
WHERE confirmed IS DISTINCT FROM TRUE
しかし、それはここでは役に立ちません。反対に、インデックスもそうではありません。とにかく、テーブル全体を書き直す必要があります。それを回避する方法はありません。ただし、これを高速化するためにできることがいくつかあります。
それはすべて、あなたが私たちと共有していないあなたのテーブルに関する情報に依存します.
あなたは言えた
update announce set confirmed = true where confirmed = false;
ブール値なので。これにより、次の 2 つのことが行われます。
まだ確認されていないアナウンスの数が 1000 万に比べて少ない場合は、フィールドをインデックスに入れ、postgresql にインデックスを使用させてアクセスを高速化できます。
古いバージョンの postgresql では、フリー スペース マップのサイズは固定されていました。大きなテーブルを更新すると、構成したサイズに関係なく、そのマップを超えて大きくなります。その結果、定期的に実行する必要がありました。そうしないとVACUUM FULL
、データベースが使用するディスク容量が想像を絶するほど大きくなってしまいます。