PostgreSQL Trigram 索引与 btree

PostgreSQL Trigram indexes vs btree

我的 cake 数据库有这个搜索查询,该数据库目前速度很慢,我正在寻求改进。我是 运行 PostgreSQL v. 9.6.

Table结构:

Table: Cakes
=====
id               int
cake_id          varchar
cake_short_name  varchar
cake_full_name   varchar
has_recipe       boolean
createdAt        Datetime
updatedAt        DateTime


Table: CakeViews
=========
id               int
cake_id          varchar
createdAt        Datetime
updatedAt        DateTime

查询:

    WITH myconstants (myquery, queryLiteral) as (
       values ('%a%', 'a')
    )
    
        select
        full_count,
        cake_id,
        cake_short_name,
        cake_full_name,
        has_recipe,
        views
        from (
          select
            count(*) OVER() AS full_count,
            cake_id,
            cake_short_name,
            cake_full_name,
            has_recipe
            cast((select count(*) FROM "CakeViews" as cv where "createdAt" > CURRENT_DATE - 3 and c.cake_id = cv.cake_id) as integer) as views
          from "Cakes" c, myconstants
          where has_recipe = true 
            and (cake_full_name ilike myquery or cake_short_name ilike myquery)
            or cake_full_name ilike lower(queryLiteral) or cake_short_name ilike lower(queryLiteral)) t, myconstants
        order by views desc,
          case
            when cake_short_name ilike lower(queryLiteral) then 1
            when cake_full_name ilike lower(queryLiteral) then 1
          end,
          case
            when has_recipe = true and cake_short_name ilike myquery then length(cake_short_name)
            when has_recipe = true and cake_full_name ilike myquery then length(cake_full_name)
          end
            limit 10

我对以下索引有想法,但它们并没有加快查询速度:

    CREATE EXTENSION pg_trgm;
    CREATE INDEX idx_cakes_cake_short_name ON public."Cakes" (lower(cake_short_name) varchar_pattern_ops);
    CREATE INDEX idx_cakes_cake_id ON public."Cakes" (cake_short_name);
    
    CREATE INDEX idx_cakeviews_cake_id ON public."CakeViews" (cake_id);
    CREATE INDEX idx_cakes_cake_short_name ON public."Cakes" USING gin (cake_short_name gin_trgm_ops);
    CREATE INDEX idx_cakes_cake_full_name ON public."Cakes" USING gin (cake_full_name gin_trgm_ops);

问题:

编辑:解释分析输出:here

查询“%a%”不包含任何三元组,因此索引在那里没有用处。它必须扫描整个 table。但如果您使用更长的查询,那么它们可能会有用。

索引 on "CakeViews" (cake_id) 如果是 on "CakeViews" (cake_id, "createdAt") 会更好。除了 none 你的蛋糕似乎有任何意见,所以如果是一般情况,我想这无关紧要。