3

PostgreSQL 9.1 をバックエンドとして使用するレシピ Web サイトを運営しています。ユーザーがレシピを検索すると、ユーザーが探しているものに応じてその場でクエリを作成します。たとえば、ユーザーが調理時間が 30 分未満のすべてのレシピを検索したい場合、次のクエリを生成します。

SELECT * From Recipes WHERE CookTime < 30;

特定のレシピを「非表示」にする必要があります。つまり、それらのレシピが検索に表示されることは決してありません。それらに到達する唯一の方法は、URL を直接知ることです。これを行うために、Recipes テーブルに新しい列を追加しました。

ALTER TABLE Recipes ADD COLUMN Hidden boolean not null default false;
CREATE INDEX IDX_Recipes_Hidden ON Recipes(Hidden);

私の考えは、「NOT HIDDEN」というフレーズをすべての WHERE 句にハードコーディングすることです。たとえば、上記のクエリは次のようになります。

select * from recipes where not Hidden and CookTime < 30;

私の質問:

クエリ アナライザーによると、これでビットマップが生成され、2 つのインデックスが結合されます。レシピの 99% は非表示になりません。この手法が、すべてのクエリから特定のレシピを除外するための最良かつ最速の方法であるかどうかを知りたい. 非表示のレシピ用に別のテーブルを作成するのが最も速い方法であることはわかっていますが、これは大量のリファクタリングになるため、これは避けたいと思います。

4

3 に答える 3

2

パフォーマンスの問題はありますか? ソリューションに問題がなければ、変更の必要のないものに時間を費やしても意味がありません。

ビットマップ インデックスは、異なる値があま​​りない場合に適しています。したがって、true と false しかない場合は問題ありません。

マテリアライズド ビューのようなものを構築することもできますが、これは大変な作業のようで、おそらく 2 つ目のテーブルを作成する方が簡単ですが、問題がない場合は何も変更しないでください。

postgres の MV: http://tech.jonathangardner.net/wiki/PostgreSQL/Materialized_Views

于 2012-04-19T04:27:48.837 に答える
1

行が二度と表示されないようにする最速の方法は...それらを削除することです。

ただし、何らかの目的で丸めたいが、ほとんどすべてのクエリには丸めたくない場合は、テーブルの名前を変更して、その場所に新しいビューを作成できます。

ALTER TABLE Recipes RENAME TO AllRecipes;
ALTER TABLE AllRecipes ADD Hidden BOOLEAN NOT NULL DEFAULT FALSE;
CREATE VIEW Recipes AS SELECT * FROM AllRecipes WHERE NOT Hidden;

これは、書き換える必要があるコードの量の点で最速です (Recipies でアプリに多くのクエリがあり、すべてのクエリから非表示のクエリを除外すると仮定します)。

しかし、パフォーマンスを高速化するための簡単なオプションも提供します。まず、非表示にインデックスを追加できます。ただし、VisibleRecipes と HiddenRecipies の 2 つのサブテーブルに分割することもできます。ビュー Recipes は、VisibleRecipies のものを正確に表示します。

ただし、テーブル AllRecipies は、パーティションとして VisibleRecipes と HiddenRecipes を持つ親テーブルであるか、ビュー自体である可能性があります。

于 2012-04-19T05:59:52.453 に答える
0

パフォーマンスに問題がなければOKです。

私がエンジンだったら、インデックスを使用して CookTime が 30 未満のテーブル行を取得し、その後、hidden = true の行をフィルター処理します。これを強制する方法 (cooktime インデックスのみを使用) を知っている場合は、テストしても問題ありません。

しかし、アナライザーが 2 つのインデックスの使用をより速く見つけた場合...

収集されたテーブルとインデックスに関する統計があることを確認してください。(私は Postgres ではなく、Oracle の専門知識を持っています)

于 2012-04-19T05:42:55.567 に答える