Postgres在使用date()函数时不使用索引

luk*_*tei 2 sql database postgresql indexing database-optimization

我的架构是

CREATE TABLE a (
  id     BIGINT PRIMARY KEY,
  dt     TIMESTAMP NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

我在dt上创建了一个索引:

CREATE INDEX a_dt_index ON a (dt);
Run Code Online (Sandbox Code Playgroud)

当我使用像这样的查询时,索引工作正常

SELECT *
FROM a
WHERE dt >= '2008-12-30' AND dt < '2008-12-31';
Run Code Online (Sandbox Code Playgroud)

但是,当我使用date()函数时,不使用索引.

SELECT *
FROM a
WHERE date(dt) = '2008-12-30'
Run Code Online (Sandbox Code Playgroud)

在我看来,这两个查询在语义上是相同的,那么为什么索引没有被使用?为什么我必须创建一个显式的date()索引?

CREATE INDEX a_date_index ON a (date(dt));
Run Code Online (Sandbox Code Playgroud)

Ati*_*gur 5

您可以阅读以下链接以了解有关索引和日期的更多信息.但TL; DR

函数是数据库的黑盒子.

因此

如果在where子句中使用任何函数,则需要使用该函数创建显式索引.数据库无法理解您的语义等效性.

它类似于案例

 WHERE UPPER(NAME)
Run Code Online (Sandbox Code Playgroud)

不在NAME列中使用索引.根据数据库UPPER功能与BLACKBOX没有什么不同.代替它.

 WHERE BLACKBOX(NAME)
Run Code Online (Sandbox Code Playgroud)