(AKA - 查询和数据非常类似于问题“选择按某列排序而在另一列上不同的行”,我怎样才能让它快速运行)。11. Postgres
我有一个表格prediction
,(article_id, prediction_date, predicted_as, article_published_date)
它代表分类器对一组文章的输出。
新文章经常被添加到单独的表中(由 FK 表示article_id
),并且在我们调整分类器时添加新的预测。
样本数据:
| id | article_id | predicted_as | prediction_date | article_published_date
| 1009381 | 362718 | negative | 2018-07-27 | 2018-06-26
| 1009382 | 362718 | positive | 2018-08-12 | 2018-06-26
| 1009383 | 362719 | positive | 2018-08-13 | 2010-09-22
| 1009384 | 362719 | positive | 2018-09-28 | 2010-09-22
| 1009385 | 362719 | negative | 2018-10-01 | 2010-09-22
创建表脚本:
create table prediction
(
id serial not null
constraint prediction_pkey
primary key,
article_id integer not null
constraint prediction_article_id_fkey
references article,
predicted_as classifiedas not null,
prediction_date date not null,
article_published_date date not null
);
create index prediction_article_id_prediction_date_idx
on prediction (article_id asc, prediction_date desc);
我们经常希望查看每篇文章的最新分类。为此,我们使用:
SELECT DISTINCT ON (article_id) article_id, id, article_published_date
FROM prediction
ORDER BY article_id, prediction_date desc
它返回类似:
| id | article_id | predicted_as | prediction_date | article_published_date
| 120950 | 1 | negative | 2018-06-29 | 2018-03-25
| 120951 | 2 | negative | 2018-06-29 | 2018-03-19
使用 上的索引(article_id, prediciton_date desc)
,此查询运行得非常快(~15ms)。这是解释计划:
Unique (cost=0.56..775374.53 rows=1058394 width=20)
-> Index Scan using prediction_article_id_prediction_date_id_idx on prediction (cost=0.56..756071.98 rows=7721023 width=20)
到现在为止还挺好。
当我想按 article_published_field 对该结果进行排序时,就会出现问题。例如:
explain (analyze, buffers)
select *
from (
select distinct on (article_id) article_id, id, article_published_date
from prediction
order by article_id, prediction_date desc
) most_recent_predictions
order by article_published_date desc
limit 3;
这可行,但查询需要大约 3-4 秒才能运行,这使得直接使用它来响应 Web 请求太慢了。
这是解释计划:
Limit (cost=558262.52..558262.53 rows=3 width=12) (actual time=4748.977..4748.979 rows=3 loops=1)
Buffers: shared hit=7621849 read=9051
-> Sort (cost=558262.52..560851.50 rows=1035593 width=12) (actual time=4748.975..4748.976 rows=3 loops=1)
Sort Key: most_recent_predictions.article_published_date DESC
Sort Method: top-N heapsort Memory: 25kB
Buffers: shared hit=7621849 read=9051
-> Subquery Scan on most_recent_predictions (cost=0.43..544877.67 rows=1035593 width=12) (actual time=0.092..4508.464 rows=1670807 loops=1)
Buffers: shared hit=7621849 read=9051
-> Result (cost=0.43..534521.74 rows=1035593 width=16) (actual time=0.092..4312.916 rows=1670807 loops=1)
Buffers: shared hit=7621849 read=9051
-> Unique (cost=0.43..534521.74 rows=1035593 width=16) (actual time=0.090..4056.644 rows=1670807 loops=1)
Buffers: shared hit=7621849 read=9051
-> Index Scan using prediction_article_id_prediction_date_idx on prediction (cost=0.43..515295.09 rows=7690662 width=16) (actual time=0.089..3248.250 rows=7690662 loops=1)
Buffers: shared hit=7621849 read=9051
Planning Time: 0.130 ms
Execution Time: 4749.007 ms
有什么方法可以让这个查询运行得更快,还是我必须求助于刷新物化视图或设置触发系统来快速获取这些数据?
以供参考:
- 该
prediction
表有 770 万行 - 表中有 1.7M distinct
article_id
sprediction
- 有一个索引
(article_id, prediciton_date desc)
和一个索引article_published_date desc
VACUUM ANALYSE
已运行