3

私は本質的にこれである非常に単純なクエリを持っています:

Select * from my_table Where my_field != '';

テーブルには約 40,000 行あり、「my_field」列はテキスト フィールドです (varchar 255)

クエリの実行には約 39,000 ミリ秒かかります。空の文字列ではないものについて各レコードを調べる必要があるためだと思います。my_field 列にインデックスを付けましたが、何も変更されていません。

念のため、クエリプランは次のとおりです。

"Seq Scan on my_table  (cost=0.00..3468.91 rows=39744 width=459)"
"  Filter: ((my_field)::text <> ''::text)"

ここで私の最良の選択肢は何ですか?

説明する 分析する:

"Seq Scan on my_table  (cost=0.00..3468.91 rows=39730 width=459) (actual time=0.021..13.763 rows=39714 loops=1)"
"  Filter: ((my_field)::text <> ''::text)"
"Total runtime: 14.856 ms"

これらのインデックスを追加しました

CREATE INDEX aa_idx ON my_table(my_field);
CREATE INDEX aa_idx ON my_table(my_field) WHERE my_field <> '';

Postgres 9.1 です

編集: [2013-02-26 00:04GMT]

チェック制約として「my_field」にパーティションを作成する利点はありますか?

CHECK(my_field = '') のようなもので、パーティション 2 では CHECK(my_field != '')

私が持っているのは、行がたくさんあるテーブルだけだと思いますか?しかし、これは、パーティションに約 80% のデータが含まれていても、select != '' クエリの実行速度が大幅に向上することを意味するでしょうか?

全文検索も調べましたが、これはOTTのようでした。列を 0 または 1 (bool) の int にすることも検討しましたが、これはパフォーマンスに影響しませんでした (= 1 はまだ多くの行を返すためだと思います)。

4

1 に答える 1

2

インデックスは役に立ちません。削除を統合するためのより良い方法を見つける必要があると思います。

実行に39秒かかると言いますが、提供した実際のクエリプランの実行には15ミリ秒かかります。これは、約2000分の1です。TOASTされた値がたくさんある非常に幅の広いテーブルについて話しているのでない限り、キャッシュがそれだけ役立つ場合を想像するのに苦労しています。これは、実際の問題は選択ではなく、パイプラインの他の場所にあることを示しています。これには往復費用が含まれる可能性がありますが、削除を行っています。

私の推奨は、ステートメントの統合を検討することです。これは、ラウンドトリップを回避し、できるだけ多くのロジックを単一のクエリにプッシュすることを意味します。完全なコンテキストを投稿していないので、ラウンドトリップなしで挿入、更新、および削除をまとめてバッチ処理するために、書き込み可能なCTEを調べることをお勧めします。

于 2013-03-07T04:11:15.667 に答える