【问题标题】:Practical limitations of expression indexes in PostgreSQLPostgreSQL 中表达式索引的实际限制
【发布时间】:2011-09-10 00:11:51
【问题描述】:

我需要使用 HSTORE 类型和按键索引来存储数据。

CREATE INDEX ix_product_size ON product(((data->'Size')::INT))
CREATE INDEX ix_product_color ON product(((data->'Color')))
etc.

使用表达式索引有哪些实际限制?在我的例子中,可能有数百种不同类型的数据,因此有数百种表达索引。每个插入、更新和选择查询都必须针对这些索引进行处理才能选择正确的索引。

【问题讨论】:

  • 我用的是最新版的PG。

标签: sql database-design postgresql expression indexing


【解决方案1】:

我从来没有玩过 hstore,但是当我需要一个 EAV 列时,我会做类似的事情,例如:

create index on product_eav (eav_value) where (eav_type = 'int');

这样做的限制是您需要在查询中明确使用它,即此查询不会使用上述索引:

select product_id
from product_eav
where eav_name = 'size'
and eav_value = :size;

但是这个会:

select product_id
from product_eav
where eav_name = 'size'
and eav_value = :size
and type = 'int';

在您的示例中,它可能更像:

create index on product ((data->'size')::int) where (data->'size' is not null);

这应该避免在没有大小条目时添加对索引的引用。根据您使用的 PG 版本,可能需要像这样修改查询:

select product_id
from products
where data->'size' is not null
and data->'size' = :size;

常规索引和部分索引之间的另一个重大区别是后者不能在表定义中强制执行唯一约束。这将成功:

create unique index foo_bar_key on foo (bar) where (cond);

以下不会:

alter table foo add constraint foo_bar_key unique (bar) where (cond);

但这会:

alter table foo add constraint foo_bar_excl exclude (bar with =) where (cond);

【讨论】:

  • 谢谢。我不清楚你为什么说需要“(data->'size' is not null)”。来自 PostgreSQL 的站点::部分索引是建立在表的子集上的索引;子集由条件表达式(称为部分索引的谓词)定义。索引只包含满足谓词的那些表行的条目。”所以如果我不添加特定的 HSTORE 键,肯定不会有索引条目。
  • 在索引中,如果没有 where 子句,无论大小是否定义,索引都会为每个条目添加一个条目。部分索引(带有 where 子句)解决了这个问题,它只为满足条件的行添加一个条目。这使得索引更小,因为它只包含相关行的条目。
  • 啊,您只是确保它不会为使用键的空值定义数据的情况添加索引条目。好吧,我没想到会发生这种情况,但我明白你的意思。
  • 呵呵,确实发生了,这是部分索引有用的众多情况之一。 :-)
  • 更正:我的意思是一个表达式索引。
猜你喜欢
  • 1970-01-01
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 2014-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多