【发布时间】: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