【问题标题】:Optimize Django queryset query with Postgres使用 Postgres 优化 Django 查询集查询
【发布时间】:2019-07-21 02:36:12
【问题描述】:

我正在使用 Django 2.1 和 python 3.6 我有一个包含其他查询的查询,当需要处理大量数据时,评估似乎需要很长时间。 基本上它达到了 db 用户超时(10 秒),所以查询失败,当我在没有超时的情况下尝试它时,几乎一分钟后我从 DB(postgres)收到以下错误消息:

ERROR:  canceling statement due to conflict with recovery
DETAIL:  User query might have needed to see row versions that must be removed.

我的问题是 - 我怎样才能使查询更有效率? (所有使用的字段都在数据库中索引)

这是查询:

migration_set__qs = Migration.objects.filter(
        migration_id=migration_id,
        migration_version=migration_version,
        migration_data__generated_id__isnull=False
    ).values_list(
        'object_id',
        flat=True
    )

containers__qs = Container.objects.all().exclude(
            Q(id__in=migration_set__qs) | Q(created_at__gte=turned_on_date)
        )

limited_containers = containers__qs[0:10]
num_containers_processed += limited_containers.count()

'count()' 触发查询的评估并在那里中断。

【问题讨论】:

  • 您的object_id 是外键吗?你知道migration_set__qs返回的id的大概数量吗?
  • @mfrackowiak - 它不是外键。大约 122k

标签: python django postgresql django-queryset


【解决方案1】:

我会尝试的第一件事是将 migration_set_qs 更改为 Subquery

migration_set__qs = Migration.objects.filter(
    migration_id=migration_id,
    migration_version=migration_version,
    migration_data__generated_id__isnull=False
).values(
    'object_id',
)

containers__qs = Container.objects.all().exclude(
    Q(id__in=Subquery(migration_set__qs)) | Q(created_at__gte=turned_on_date)
)

limited_containers = containers__qs[0:10]
num_containers_processed += limited_containers.count()

虽然我不确定它是否能解决你所有的问题。如果有任何不同,请告诉我,如果我有任何其他想法,我也会更新这个答案。

【讨论】:

  • 谢谢@mfrackowiak。但结果是一样的。无论如何它都会创建子查询。
猜你喜欢
  • 2018-11-08
  • 1970-01-01
  • 2022-01-24
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-22
相关资源
最近更新 更多