我在Postgres9和Postgres10中有相同的表,除了Postgres10表是按状态划分的。两个表中都有大约8000万条记录
当我这样查询时,在分区表上它的速度比在Postgres9未分区表上快10倍。万岁!
# This is fast with a partition, and slow without
parcels = Parcel.objects.filter(state='15', boundary__intersects=polygon)
但是,当我尝试通过Django进行更新时,分区表上的速度大约慢了1000倍(大约需要2分钟),而它是Postgres9版本上的:
for parcel in parcels:
do something
# This is slow with a partition, and fast without
parcel.save()
但是当我直接通过psql进行更新时,它在Postgres10中的分区表上非常快,而在Postgres9中的未分区表上则非常慢:
# This is fast with a partition, and slow without
UPDATE parcel SET field=42 WHERE state='15' AND parcel_id='someid';
为什么我在Django中对save
的调用比直接通过psql更新要慢得多? QuerySet.explain()
操作是否与save
等效?
答案 0 :(得分:0)
Postgres10比Postgres9慢的原因是分区表不允许在父表上使用主键。因此,我对parcel.save()
的调用试图运行类似UPDATE parcel SET field=42 WHERE "id" = 'someid';
的查询,但是在分区表上按id查询非常慢。
我通过向每个子表添加主键来解决此问题。例如。 ALTER TABLE parcel_01 ADD PRIMARY KEY (id);
。当我为每个孩子添加它时,它具有相似的效果,并且我的更新时间减少了99.9%。总体而言,在Postgres10中使用分区表可将我正在使用的工具的总运行时间减少75%(从40分钟减少到大约10分钟)
我要感谢@ 2ps建议我查看生成的SQL,并建议一种无需使用主键即可强制执行我想要的查询的方法。