ILIKE超过两列在连接表中减慢

时间:2016-07-12 08:08:46

标签: sql performance postgresql postgresql-9.4

我有两张桌子:

产品

  • product_id int
  • producer varchar
  • status char(1)

product_names

  • name_id int
  • product_id int fk
  • name vharchar
  • lang char(2)

产品有大约50万个条目。 product_names大约1 000 000

        SELECT p.*, n.name, n.lang
        FROM products p
        INNER JOIN product_names n ON 
            n.product_id = e.product_id

        WHERE
                p.status IN ('A', '1', '5', '9')

            AND (
                    n.name ILIKE 'nestle%'
                 OR p.producer ILIKE 'nestle%'
            )
        LIMIT 1

如果我只在n.name或仅p.product上运行ILIKE,则需要大约15ms才能找到结果。

如果我在同一时间在两个列上运行ILIKE,则需要大约1.2秒......再长1000倍!

我尝试了所有可能的索引:

产品:

"p_producer_index20" btree (producer)
"p_producer_index22" btree (producer text_pattern_ops)
"p_producer_index23" gist (producer gist_trgm_ops)
"p_producer_index24" gin (producer gin_trgm_ops)

product_names:

"p_names_name_index2" btree (name text_pattern_ops)
"p_names_name_trgm_index" gin (name gin_trgm_ops)

我在这里错过了什么或做了一些完全错误的事吗?

2 个答案:

答案 0 :(得分:0)

您可以在products.status上放置一个索引,以获得索引的一些好处。 由于OR,它可能没有充分利用那些生产者和名称字段上的索引。

试试看:

filename = as.character(formatC(y, width=3, flag=0))

您还可以ANALYZE表来帮助查询计划程序。

答案 1 :(得分:0)

也许尝试这样的事情:

SELECT *
FROM   (
        SELECT p.*, n.name, n.lang
        FROM products p
        JOIN product_names n ON n.product_id = e.product_id
        WHERE p.status IN ('A', '1', '5', '9') AND
              n.name ILIKE 'nestle%'
        UNION ALL
        SELECT p.*, n.name, n.lang
        FROM products p
        JOIN product_names n ON n.product_id = e.product_id
        WHERE p.status IN ('A', '1', '5', '9') AND
              p.producer ILIKE 'nestle%') t
LIMIT 1