在非唯一列上创建唯一索引

Jus*_*tin 4 sql postgresql unique-index postgresql-9.3

不确定这在 PostgreSQL 9.3+ 中是否可行,但我想在非唯一列上创建唯一索引。对于这样的表:

CREATE TABLE data (
  id SERIAL
  , day DATE
  , val NUMERIC
);
CREATE INDEX data_day_val_idx ON data (day, val); 
Run Code Online (Sandbox Code Playgroud)

我希望能够[快速]仅查询不同的日期。我知道我可以用来data_day_val_idx帮助执行不同的搜索,但如果不同值的数量大大少于索引覆盖中的行数,这似乎会增加额外的开销。就我而言,大约每 30 天就有 1 个是明显的。

创建关系表以仅跟踪唯一条目是我唯一的选择吗?思维:

CREATE TABLE days (
  day DATE PRIMARY KEY
);
Run Code Online (Sandbox Code Playgroud)

并在每次插入数据时使用触发器更新它。

Erw*_*ter 5

索引只能索引实际行,而不能索引聚合行。所以,是的,就所需的索引而言,创建一个具有您提到的唯一值的表是您唯一的选择。data.day使用从到 的外键约束强制引用完整性days.day。这对于性能来说可能也是最好的,具体取决于整体情况。

但是,由于这与性能有关,因此还有一种替代解决方案:您可以使用递归 CTE 来模拟松散索引扫描:

WITH RECURSIVE cte AS (
   (  -- parentheses required
   SELECT day FROM data ORDER BY 1 LIMIT 1
   )
   UNION ALL
   SELECT (SELECT day FROM data WHERE day > c.day ORDER BY 1 LIMIT 1)
   FROM   cte  c
   WHERE  c.day IS NOT NULL  -- exit condition
   )
SELECT day FROM cte;
Run Code Online (Sandbox Code Playgroud)

由于附加的和子句,第一个周围SELECT需要括号。看:ORDER BYLIMIT

这只需要一个简单的索引day

有多种变体,具体取决于您的实际查询:

我对你的后续问题的回答中有更多内容: