我在Windows 10上使用PostgreSQL 10.4,并且观察到了这种奇怪的缓慢性。
create table stock_prices (
quote_date timestamp,
security_id int NOT NULL,
...
PRIMARY KEY (quote_date, security_id)
);
create index stock_prices_idx2 on stock_prices (security_id, quote_date);
立即执行以下操作。
select * from stock_prices where quote_date = '2017-12-29';
但是接下来的时间是31秒。
create temp table ts (
quote_date timestamp,
primary key (quote_date)
);
insert into ts values ('2017-12-29');
select p.*
from stock_prices p, ts t
where p.quote_date = t.quote_date;
drop table ts;
AFAIK,上面应该点击索引。使用DBeaver的说明执行计划功能,它报告说它对stock_prices进行了“序列扫描”,我认为这意味着表扫描。
在我迁移到Postgres 10.4之前,我使用的SQL Server 2017 Developer Edition具有完全相同的架构,并且没有任何问题。该数据库的报价很大,因此我无法提供太多测试数据,但是基础数据直接来自沃顿商学院的WRDS学术研究数据库(我使用的表是CRSP.dsf)。知道为什么postgres不使用索引吗?
[编辑]好的,看起来很大程度上取决于Postgres认为临时表ts
中的内容。在analyze ts;
之前添加select
使其瞬时。这很奇怪,但是无论如何...
答案 0 :(得分:0)
在quote_date
表的ts
列上还有一个主键/索引。由于您在此处进行内部联接,因此优化器应可以自由选择要在联接的左侧和右侧显示哪个表。假设将stock_prices
表放在左侧,则可以利用ts.quote_date
列上的索引。但是,在这种情况下,这意味着它将扫描stock_prices
表。因此,当您切换Postgres的版本时,查询计划可能会更改,但是在这里我看不到任何意外情况。 Postgres没有使用您询问的索引,因为它似乎找到了更好的索引/表来使用。
答案 1 :(得分:0)
如上所述,添加analyze ts
将解决此问题。看起来统计数据对Postgre计划查询的方式有很大的影响。