Postgres jsonb查询缺失索引?

时间:2015-12-18 18:07:17

标签: postgresql postgresql-performance database-indexes jsonb

我们将以下json文档存储在我们的PG表(标识)中的jsonb列'data'中:

{
    "email": {
        "main": "mainemail@email.com",
        "prefix": "aliasPrefix",
        "prettyEmails": ["stuff1", "stuff2"]
    },
    ...
}

我在表格中设置了以下索引:

CREATE INDEX ix_identities_email_main
  ON identities
  USING gin
  ((data -> 'email->main'::text) jsonb_path_ops);

我错过了什么阻止了以下查询命中该索引?它在桌面上进行了完整的seq扫描......我们有数千万行,所以这个查询已经挂了超过15分钟......

SELECT * FROM identities WHERE data->'email'->>'main'='mainemail@email.com';

1 个答案:

答案 0 :(得分:2)

如果您为 data 列使用JSONB数据类型,则为了索引所有 "email" < / strong>您需要创建以下索引的条目值:

CREATE INDEX ident_data_email_gin_idx ON identities USING gin ((data -> 'email'));

另请注意,对于JSONB,您需要使用适当的运算符列表;

  

jsonb的默认GIN运算符类支持使用@&gt;的查询,   ?,?&amp;和?|运营商

以下查询将点击此索引:

SELECT * FROM identities
WHERE data->'email' @> '{"main": "mainemail@email.com"}'
-- OR
SELECT * FROM identities
WHERE data->'email' @> '{"prefix": "aliasPrefix"}'

如果需要搜索数组元素"stuff1""stuff2",上面的索引将不起作用,您需要在"prettyEmails"数组元素值上显式添加表达式索引以进行查询工作得更快。

CREATE INDEX ident_data_prettyemails_gin_idx ON identities USING gin ((data -> 'email' -> 'prettyEmails'));

此查询将点击索引:

SELECT * FROM identities
WHERE data->'email' @> '{"prettyEmails":["stuff1"]}'