取决于确切的规则 - 并实际实现CHECK
了列的约束。
如果您的列中总是有一个点,col
并且您的所有年份都有 4 位数字:
基本解决方案
SELECT * FROM tbl
WHERE col LIKE to_char(now(), '"%."YYYY');
为什么?
与相同的数据类型进行比较是最有效的。由于该列是字符类型 ( varchar
),因此请使用to_char()
(returns text
,实际上与varchar
) 而不是EXTRACT
或date_part()
(return double precision
)。
更重要的是,这个表达式是sargable。这通常是最便宜的,并且允许(可选)索引支持。在您的情况下,三元组索引将起作用:
优化
如果您想尽可能快(读取性能)和准确,并且您的表有很多行,请使用专门的部分表达式索引:
CRATE INDEX tbl_year_idx ON tbl (cast(right(col, 4) AS int) DESC)
WHERE col ~ '\.\d{4}$'; -- ends with a dot and 4 digits
匹配查询:
SELECT * FROM tbl
WHERE col ~ '\.\d{4}$' -- repeat index condition
AND right(col, 4)::int = EXTRACT(year FROM col);
用 测试性能EXPLAIN ANALYZE
。
您甚至可以更进一步,为当年定制指数:
CRATE INDEX tbl_year2015_idx ON tbl (tbl_id) -- any (useful?) column
WHERE col LIKE '%.2015';
适用于第一个“基本”查询。
您必须(重新)为每年创建索引。一个简单的解决方案是提前几年创建索引,并每年自动添加另一个索引......
这也是您考虑替代方案的地方:将年份作为冗余integer
列存储在表中并简化其余部分。
这就是我会做的。