在非唯一列上创建唯一索引
Create a unique index on a non-unique column
不确定这在 PostgreSQL 9.3+ 中是否可行,但我想在非唯一列上创建唯一索引。对于 table,例如:
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 天是不同的。
创建关系 table 以仅跟踪唯一条目是我唯一的选择吗?思考:
CREATE TABLE days (
day DATE PRIMARY KEY
);
每次我们插入数据时都会用触发器更新它。
索引只能索引实际行,不能索引聚合行。所以,是的,就所需索引而言,创建一个 table 具有您提到的唯一值是您唯一的选择。使用从 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?
更多内容在我对你的后续问题的回答中:
不确定这在 PostgreSQL 9.3+ 中是否可行,但我想在非唯一列上创建唯一索引。对于 table,例如:
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 天是不同的。
创建关系 table 以仅跟踪唯一条目是我唯一的选择吗?思考:
CREATE TABLE days (
day DATE PRIMARY KEY
);
每次我们插入数据时都会用触发器更新它。
索引只能索引实际行,不能索引聚合行。所以,是的,就所需索引而言,创建一个 table 具有您提到的唯一值是您唯一的选择。使用从 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?
更多内容在我对你的后续问题的回答中: