不确定这在 PostgreSQL 9.3+ 中是否可行,但我想在非唯一列上创建一个唯一索引。对于像这样的表:
CREATE TABLE data (
id SERIAL
, day DATE
, val NUMERIC
);
CREATE INDEX data_day_val_idx ON data (day, val);
我希望能够 [快速] 仅查询不同的日期。我知道我可以使用 data_day_val_idx
来帮助执行不同的搜索,但如果不同值的数量大大少于索引涵盖的行数,这似乎会增加额外的开销。就我而言,30 天内大约有 1 天是不同的。
创建关系表以仅跟踪唯一条目是我唯一的选择吗?思考:
CREATE TABLE days (
day DATE PRIMARY KEY
);
每次我们插入数据时用触发器更新它。
最佳答案
索引只能索引实际行,不能索引聚合行。所以,是的,就所需的索引而言,创建一个像你提到的具有唯一值的表是你唯一的选择。使用从 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;
由于附加了 ORDER BY
和 LIMIT
子句,因此需要在第一个 SELECT
周围加上括号。见:
这只需要 day
的普通索引。
有多种变体,具体取决于您的实际查询:
- Optimize GROUP BY query to retrieve latest row per user
- Unused index in range of dates query
- Select first row in each GROUP BY group?
更多内容在我对您的后续问题的回答中:
关于sql - 在非唯一列上创建唯一索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29171623/