お願いしたことができます。具体的な例(2つのテーブルのみ)を使用するには、次のように指定します。
CREATE TABLE users
(
user_id SERIAL PRIMARY KEY,
username text
) ;
-- Index to find usernames
CREATE INDEX idx_users_username_full_text
ON users
USING GIN (to_tsvector('english', username)) ;
CREATE TABLE topics
(
topic_id SERIAL PRIMARY KEY,
topic text
) ;
-- Index to find topics
CREATE INDEX idx_topics_topic_full_text
ON topics
USING GIN (to_tsvector('english', topic)) ;
PostgreSQLのドキュメントを参照してください。 Controlling Text Searchにto_tsvector
の説明があります。
...移入テーブル
INSERT INTO users
(username)
VALUES
('Alice Cooper'),
('Boo Geldorf'),
('Carol Burnet'),
('Daniel Dafoe') ;
INSERT INTO topics
(topic)
VALUES
('Full text search'),
('Fear of void'),
('Alice in Wonderland essays') ;
...私たちは、そのビューを検索
CREATE VIEW search_items AS
SELECT
text 'users' AS origin_table, user_id AS id, to_tsvector('english', username) AS searchable_element
FROM
users
UNION ALL
SELECT
text 'topics' AS origin_table, topic_id AS id, to_tsvector('english', topic) AS searchable_item
FROM
topics ;
両方のテーブルから値を組み合わせたビューを作成します。
SELECT
*
FROM
search_items
WHERE
plainto_tsquery('english', 'alice') @@ searchable_element
..あなたはほとんどの場合、searchable_element
を無視する必要があります。あなたはほとんどの場合、origin_table
とid
に興味があります。
origin_table | id | searchable_element
:----------- | -: | :--------------------------------
users | 1 | 'alic':1 'cooper':2
topics | 3 | 'alic':1 'essay':4 'wonderland':3
参照解析plainto_tsquery
機能の説明のためのクエリ、およびまた@@
operator。
インデックスが使用されていることを確認する:
EXPLAIN ANALYZE
SELECT
*
FROM
search_items
WHERE
plainto_tsquery('english', 'alice') @@ searchable_element
| QUERY PLAN |
| :----------------------------------------------------------------------------------------------------------------------------------------- |
| Append (cost=12.05..49.04 rows=12 width=68) (actual time=0.017..0.031 rows=2 loops=1) |
| -> Bitmap Heap Scan on users (cost=12.05..24.52 rows=6 width=68) (actual time=0.017..0.018 rows=1 loops=1) |
| Recheck Cond: ('''alic'''::tsquery @@ to_tsvector('english'::regconfig, username)) |
| Heap Blocks: exact=1 |
| -> Bitmap Index Scan on idx_users_username_full_text (cost=0.00..12.05 rows=6 width=0) (actual time=0.005..0.005 rows=1 loops=1) |
| Index Cond: ('''alic'''::tsquery @@ to_tsvector('english'::regconfig, username)) |
| -> Bitmap Heap Scan on topics (cost=12.05..24.52 rows=6 width=68) (actual time=0.012..0.012 rows=1 loops=1) |
| Recheck Cond: ('''alic'''::tsquery @@ to_tsvector('english'::regconfig, topic)) |
| Heap Blocks: exact=1 |
| -> Bitmap Index Scan on idx_topics_topic_full_text (cost=0.00..12.05 rows=6 width=0) (actual time=0.002..0.002 rows=1 loops=1) |
| Index Cond: ('''alic'''::tsquery @@ to_tsvector('english'::regconfig, topic)) |
| Planning time: 0.098 ms |
| Execution time: 0.055 ms |
インデックスは、実際に使用されている(Bitmap Index Scan on idx_topics_topic_full_text
とBitmap Index Scan on idx_users_username_full_text
を参照してください)。
あなたはdbfiddle here
NOTEにすべてを確認することができます。'english'
は、インデックスとクエリに選ばれたtext search configurationです。あなたのケースに適したものを選んでください。既存のものがあなたのニーズを満たしていない場合は、自分で作成することができます。
このようなことができます。元の表の必要な列(または式)に正しい索引があることを確認します。また、ビューをクエリするときに生成された実行計画をテストし、インデックスの使用状況を確認します。それ以外の場合は動作しますが、実際は非常にゆっくりです。あるいは、*マテリアライズド・ビュー*を持ち、その上に直接索引を付けることもできます。頻繁に更新するようにしてください。 – joanolo