我的架构是
CREATE TABLE a (
id BIGINT PRIMARY KEY,
dt TIMESTAMP NOT NULL
);
我在dt上创建了一个索引:
CREATE INDEX a_dt_index ON a (dt);
当我使用像
这样的查询时,索引工作正常SELECT *
FROM a
WHERE dt >= '2008-12-30' AND dt < '2008-12-31';
但是当我使用date()函数时,索引没有被使用。
SELECT *
FROM a
WHERE date(dt) = '2008-12-30'
在我看来,这两个查询在语义上是相同的,那么为什么不使用索引呢? 为什么我必须创建一个明确的date()索引?
CREATE INDEX a_date_index ON a (date(dt));
答案 0 :(得分:5)
您可以阅读以下链接,详细了解indexes and date。但TL; DR
函数是数据库的黑盒子。
因此
如果在where子句中使用任何函数,则需要使用该函数创建显式索引。数据库不理解您的语义等效性。
类似于
的情况 WHERE UPPER(NAME)
不在NAME列中使用索引。根据数据库UPPER功能与BLACKBOX没有区别。替换它。
WHERE BLACKBOX(NAME)
答案 1 :(得分:1)
查看使用日期函数的示例输出
postgres# select id, date(dt), dt from a;
id | date | dt
----+------------+----------------------------
1 | 2014-12-15 | 2014-12-15 16:32:13.942183
2 | 2014-12-15 | 2014-12-15 16:34:05.480178
(2 rows)
Time: 2.190 ms
存储的数据类型不同。
其他人可能会以不同的方式使用该功能:
postgres# SELECT *
FROM a
WHERE dt >= '2014-12-15 16:33' AND dt < '2014-12-16 ';
id | dt
----+----------------------------
2 | 2014-12-15 16:34:05.480178
(1 row)
Time: 2.168 ms
postgres# SELECT *
FROM a
WHERE date(dt) >= '2014-12-15 16:33' AND dt < '2014-12-16 ';
id | dt
----+----------------------------
1 | 2014-12-15 16:32:13.942183
2 | 2014-12-15 16:34:05.480178
(2 rows)
我没有在docs中找到这个功能!!但这里是描述:
postgres# \df+ date()
List of functions
Schema | Name | Result data type | Argument data types | Type | Security | Volatility | Owner | Language | Source code | Description
------------+------+------------------+-----------------------------+--------+----------+------------+----------+----------+------------------+------------------------------------------
pg_catalog | date | date | abstime | normal | invoker | stable | postgres | internal | abstime_date | convert abstime to date
pg_catalog | date | date | timestamp without time zone | normal | invoker | immutable | postgres | internal | timestamp_date | convert timestamp to date
pg_catalog | date | date | timestamp with time zone | normal | invoker | stable | postgres | internal | timestamptz_date | convert timestamp with time zone to date
(3 rows)