【问题标题】:Postgresql full text search 8 times slower than sqlite fts searchPostgresql 全文搜索比 sqlite fts 搜索慢 8 倍
【发布时间】:2021-02-17 15:17:14
【问题描述】:

所以我想做一些全文搜索,查找如何使用 sqlite 进行搜索,实现了它并认为它很慢。所以我选择了 postgresql,因为我在过去几年一直在使用该数据库。

我有一个非常简单的表 + 触发器和一个索引:

CREATE TABLE submission
(
    id           TEXT NOT NULL,
    subreddit_id TEXT NOT NULL,
    author       TEXT,
    created_utc  INTEGER,
    title        TEXT NOT NULL,
    selftext     TEXT,
    permalink    TEXT,
    num_comments INTEGER,
    score        FLOAT,
    upvote_ratio FLOAT,
    fts          TSVECTOR,
    UNIQUE (id, subreddit_id)
);
CREATE FUNCTION submission_fts_trigger() RETURNS trigger AS
$$
BEGIN
    new.fts :=
                setweight(to_tsvector('pg_catalog.english', new.title), 'A') ||
                setweight(to_tsvector('pg_catalog.english', new.selftext), 'B');
    return new;
END;
$$ LANGUAGE plpgsql;
    
CREATE TRIGGER trg_submission_idx_fts_update
    BEFORE INSERT OR UPDATE
    ON submission
    FOR EACH ROW
EXECUTE FUNCTION submission_fts_trigger();

CREATE INDEX search_idx_fts_idx ON submission USING GIN (fts);

sql query for search
"SELECT * FROM submission, plainto_tsquery('foostring') AS q WHERE (fts @@ q);"

现在,虽然它的工作原理比 sqlite 解决方案慢 8 倍,这有点奇怪,但我预计会有不同的结果。我也环顾四周,根据一些博客文章,上面的解决方案似乎应该很快。 目前我在表中的数据大约是 1500 行。

在 postgresql 中进行一次搜索大约需要 32 毫秒,在 sqlite 中进行一次搜索需要 4 毫秒。

我错过了什么吗?有没有办法让 postgresql 中的搜索更快?如果我向表中添加更多数据,sqlite 会变慢吗?

像弹性搜索这样的东西会更快吗?

edit explain(analyze,buffers)的结果是:

Nested Loop  (cost=12.31..36.12 rows=7 width=876) (actual time=2.517..2.518 rows=1 loops=1)
   Buffers: shared hit=34
  ->  Function Scan on plainto_tsquery q  (cost=0.25..0.26 rows=1 width=32) (actual time=2.472..2.472 rows=1 loops=1)   
        Buffers: shared hit=29 
  ->  Bitmap Heap Scan on submission  (cost=12.06..35.79 rows=7 width=844) (actual time=0.040..0.040 rows=1 loops=1)
        Recheck Cond: (fts @@ q.q)
        Heap Blocks: exact=1
        Buffers: shared hit=5
        ->  Bitmap Index Scan on search_idx_fts_idx  (cost=0.00..12.05 rows=7 width=0) (actual time=0.029..0.029 rows=1 loops=1)
              Index Cond: (fts @@ q.q)
              Buffers: shared hit=4
Planning:
 Buffers: shared hit=188
Execution Time: 2.611 ms

编辑 2 所以,我的测量来自调用 select 语句的函数,这对于 sqlite 和 postgresql 都是一样的。感谢分析器,我可以看到 postgresql 足够快,而且我正在使用的 jdbc 包装器似乎增加了很多开销。
谢谢指点。

【问题讨论】:

  • EXPLAIN(ANALYZE, BUFFERS) 的结果是什么?
  • 看起来查询已经非常快了,我不确定弹性是否会更好,但这个查询很快。
  • Postgres 中的查询耗时不到 3ms 而不是 32
  • 在 PostgreSQL 中为 2.6 毫秒,在 SQLite 中为 4 毫秒。这使 PostgreSQL 稍微快了一点,而不是慢了

标签: postgresql sqlite full-text-search


【解决方案1】:

感谢这里的 cmets,很明显这不是数据库故障。所以我做了一些挖掘,最后记得我还没有添加连接池,而是为每个数据库请求打开一个新的 SQL 连接。

事实证明,这样做需要比使用连接池多 10 倍的时间。

使用连接池后,postgresql 全文搜索会稍微快一些,我现在的设置约为 10%。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    相关资源
    最近更新 更多