【问题标题】:Is it possible to create a PostgreSQL index with json Include Columns?是否可以使用 json Include Columns 创建 PostgreSQL 索引?
【发布时间】:2021-08-27 16:22:51
【问题描述】:

我使用的是 PostgreSQL 11.8

CREATE INDEX ix_products_product_sku_with_json_columns
ON products USING btree((product_sku))
INCLUDE ((data->>'variantCode'));

错误:包含的列中不支持表达式
SQL 状态:0A000

Documentation 说:

不支持将表达式作为包含列,因为它们不能用于仅索引扫描。

我想data->>'variantCode' 是一个表达式,这就是故事的结局?
我可以看到两种解决方法,但没有一种对我有吸引力:

  • 在表中创建一个专用的 VariantCode 常规 SQL 列
  • data->>'variantCode' 作为索引键的一部分

第二个选项有多糟糕?
最终目标是在以下查询中执行Index-Only Scan

SELECT data->>'variantCode', ARRAY_AGG(product_sku)
FROM products
GROUP BY data->>'variantCode'

【问题讨论】:

    标签: postgresql indexing postgresql-11


    【解决方案1】:

    您不能将data->>'variantCode' 作为INCLUDE 列,但也将其添加为索引键不会帮助您获得仅索引扫描。对于仅索引扫描,PostgreSQL 不考虑不是列的索引键。没有根本问题可以阻止它,只是没有实施。

    您必须将整个 data 添加到索引中,但这是不可能的,因为 jsonb 没有 B-tree 运算符类。

    因此,获得仅索引扫描的唯一剩余选项是生成列:

    ALTER TABLE products ADD data_varcode text
       GENERATED ALWAYS AS (data->>'variantCode') STORED;
    

    然后您可以在查询和索引中使用该列。

    【讨论】:

    • 确实,我无法使用索引键中的 json 列实现仅索引扫描,只能使用位图堆扫描。不幸的是,我正在运行不包含生成列的 PostgreSQL 11.8,但我仍然可以创建一个常规列。谢谢
    猜你喜欢
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多