7

我正在爲我正在構建的網站創建自定義論壇軟件,其中包括2個表(與此問題相關):topicsposts。帖子屬於一個主題,主題包含主題,而每個帖子都包含主題。動態或列化tsvector索引?

下面是有關我的問題列的基本表結構:

CREATE TABLE topics (
    id bigserial NOT NULL, 
    title varchar(128) NOT NULL, 
    created timestamp with time zone NOT NULL default NOW(), 
    updated timestamp with time zone NOT NULL default NOW(), 
    PRIMARY KEY (id) 
); 

CREATE TABLE posts (
    id bigserial NOT NULL, 
    topic_id bigint NOT NULL REFERENCES topics(id) ON DELETE CASCADE, 
    body text NOT NULL, 
    created timestamp with time zone NOT NULL default NOW(), 
    updated timestamp with time zone NOT NULL default NOW(), 
    PRIMARY KEY (id) 
); 

下面是關於建立全文索引我的兩個選項。

選項1:在標題/主體列上創建動態tsvector索引。

CREATE INDEX topics_title_idx ON topics USING gin(to_tsvector(title)); 
CREATE INDEX posts_body_idx ON posts USING gin(to_tsvector(body)); 

選項2:創建額外的列舉行的tsvector-美化版標題/身體數據,並在這些添加索引。

ALTER TABLE topics ADD COLUMN topics_vector tsvector NOT NULL; 
CREATE TRIGGER topics_ins BEFORE INSERT OR UPDATE ON topics FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(title_vector, 'pg_catalog.english', title); 
CREATE INDEX topics_title_idx ON topics USING gin(title_vector); 

ALTER TABLE posts ADD COLUMN posts_vector tsvector NOT NULL; 
CREATE TRIGGER posts_ins BEFORE INSERT OR UPDATE ON posts FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(body_vector, 'pg_catalog.english', body); 
CREATE INDEX posts_body_idx ON posts USING gin(body_vector); 

因爲選項1中的兩個之間我辯論會來救我的磁盤空間,但速度較慢提供搜索,並選擇2將需要額外的磁盤空間,同時提供更快的搜索。

讓我們假裝有20個新主題&每天100篇新帖子。你會選擇哪一個?如果每天的主題/帖子數量是兩倍,那該怎麼辦?那五次?十次?你對一個人的決定是否會改變?

回答

4

使用選項1不會讓您的搜索更慢。

將使用GIN索引,無論您是否在實例化列或計算表達式中創建索引。

你只需要更改查詢語法:

SELECT * 
FROM posts 
WHERE TO_TSVECTOR('english', title) @@ myquery 

在第一種情況下,或

SELECT * 
FROM posts 
WHERE title_vector @@ myquery 
在第二種情況下

在實例化列上使用TS_RANK時,您可能會節省一點時間。

+0

嗯,也許我在手冊中誤讀了一些東西,因爲我留下了一個印象,那就是像選項2那樣更快。 – 2009-10-30 19:02:41

+1

如果你正在使用'TS_VECTOR'本身進行操作,比如'TS_RANK' ,那麼選項'2'會更快。如果您只使用'TS_VECTOR'進行搜索,則性能將保持不變。持久化列甚至不會被優化器引用。 – Quassnoi 2009-10-30 19:34:58

+0

很高興知道。我要按排名排序,所以我最終可能會使用選項2.謝謝! – 2009-10-30 22:56:30

4

讓我們假設有20個新的話題每天 & 100新職位。您會選擇哪一種 ?如果每天的 話題/帖子的數量是多少? 五倍那?十次?你的 決定一個與另一個改變?

這是一年約36,000個職位。沒關係。即使在便宜的機器上,這可能與十次無關。

但是,您可能需要一個第三個表,其中包含將主題和正文組合在一起的顯式tsvector。然後,您可以使用內置加權系統並運行一次搜索,以提供人們通常在論壇上期望的搜索類型等。這意味着編寫自定義觸發器來更新您的tsvector,當任何源表被更改時。

2

通常情況下,我會將tsvector存儲在一個字段中,因爲這也會讓您有用的訪問headline()和rank()之類的東西。