【问题标题】:How to avoid ordering by in django queryset, order_by() not working如何避免在 django 查询集中排序,order_by() 不起作用
【发布时间】:2020-07-15 13:33:07
【问题描述】:

我有一个“大”数据库,其中包含超过 60M 条记录,我正在尝试按 50 分页。 我有另一个带有~8M 记录的数据库,它运行良好,但是使用 60M 的数量,它永远不会加载和溢出数据库。 我发现问题出在 django 制作的 order_by(id) 上,所以我尝试使用已经按 id 排序的 mysql 视图,但随后 django 尝试再次对其进行排序。为了避免这种情况,我使用了 order_by(),它应该避免任何排序,但它仍然这样做。

    def get_queryset(self, request):
        qs = super(CropAdmin, self).get_queryset(request)

        qs1 = qs.only('id', 'grain__id', 'scan__id', 'scan__acquisition__id',
                      'validated', 'area', 'crop_date', 'matched_label', 'grain__grain_number', 'filename').order_by()

        if request.user.is_superuser:
            return qs1

查询仍然使用order_by:

SELECT `crops_ordered`.`crop_id`,
       `crops_ordered`.`crop_date`,
       `crops_ordered`.`area`,
       `crops_ordered`.`matched_label`,
       `crops_ordered`.`validated`,
       `crops_ordered`.`scan_id`,
       `crops_ordered`.`grain_id`,
       `crops_ordered`.`filename`,
       `scans`.`scan_id`,
       `scans`.`acquisition_id`,
       `acquisitions`.`acquisition_id`,
       `grains`.`grain_id`,
       `grains`.`grain_number`
  FROM `crops_ordered`
 INNER JOIN `scans`
    ON (`crops_ordered`.`scan_id` = `scans`.`scan_id`)
 INNER JOIN `acquisitions`
    ON (`scans`.`acquisition_id` = `acquisitions`.`acquisition_id`)
 INNER JOIN `grains`
    ON (`crops_ordered`.`grain_id` = `grains`.`grain_id`)
 **ORDER BY `crops_ordered`.`crop_id` DESC**
 LIMIT 50

关于如何解决这个问题的任何想法?还是使用这种大小的数据库的更好方法?

【问题讨论】:

  • 所以打印的查询是str(qs1.query),打印在if 行之前?只要确保没有其他干扰。
  • @Melvyn 是的,没错!
  • 不知道你是不是using MyISAM。在健全的数据库上按 PK 排序不应导致表扫描。根据文档,您做的一切都是正确的。您是否尝试过使用 Django 提出错误?
  • 我使用 innodb 作为引擎。实际上,您走在正确的道路上,对于具有误导性的答案感到抱歉。我再次查看了带有和不带有 order_by() 的 str(qs1.query): 1) 带有 order_by() 的查询不对记录进行排序 2) 没有 order_by() 的查询对它们进行排序但是之后如果 1) 当我使用 django-debug-toolbar 查看查询,它添加了排序,所以它必须是其他添加它的东西。我删除了模型中的ordering_by id,会不会是分页?
  • 分页器只添加关于无序查询集的警告。在默认的 ModelAdmin 中,任何排序都适用于 get_queryset()get_field_queryset() 是另一个候选人,但我认为 Crop 是主要模型,而不是相关模型,所以它不适合。我不明白 Django 是如何做到这一点的,它必须在您的代码或应用程序中。我将从get_queryset() 的消费者开始(右键单击方法名称-> 在 PyCharm 中查找用法)。

标签: python django optimization


【解决方案1】:

我不相信order_by() 会起作用,因为当 Django 实现这个功能时,很可能会有一个默认参数。说了这么多,相信this thread有你想要的答案。

编辑

该线程中的链接可能一次提供了太多信息,尽管也没有太多详细信息。如果你不喜欢 Github,这个方法还有一个 official documentation page,但你必须手动查找 clear_ordering,使用 CTRL + f 或任何等效项。

【讨论】:

  • 好吧,我认为那篇文章中的建议是我已经尝试过的,来自文档:**如果您不希望将任何排序应用于查询,甚至不希望使用默认排序,不带参数调用 order_by()。 **
  • 您是否尝试过链接为“此线程”的文章?它使用了clear_ordering,我不确定你是否尝试过——here,以防你找不到它。
猜你喜欢
  • 2019-12-02
  • 1970-01-01
  • 2012-04-07
  • 1970-01-01
  • 2015-11-15
  • 1970-01-01
  • 2014-11-15
  • 1970-01-01
  • 2023-01-22
相关资源
最近更新 更多