在一个字段上过滤并在另一个字段上排序时 Django 模型的最佳索引

Best index for a Django model when filtering on one field and ordering on another field

我使用链接到 PostgreSQL 的 Django 2.2 并想优化我的数据库查询。 给定以下简化模型:

class Person(model.Models):
    name = models.CharField()
    age = models.Integerfield()

我必须对其执行以下查询,比如说,

Person.objects.filter(age__gt=20, age__lt=30).order_by('name')

在模型元字段中定义索引以优化查询的最佳方式是什么? 这四个选项中哪个最好?

    class Meta
        indexes = [models.Index(fields=['age','name']),
                   models.Index(fields=['name','age']),
                   models.Index(fields=['name']),
                   models.Index(fields=['age'])]

例如,是否可以在查询完成时阻止排序?谢谢。

# You should apply indexing on age, because you are searching for 'age' column data

indexes = [
    models.Index(fields=['age'])
]

这真的是一个 postgres 问题,和 Django 问题一样多,对吧?

我认为 很有可能在您的排序字段上创建索引将有助于提高性能。但是有很多注意事项,如果它对你真的很重要,你可能想做一些针对 Postgres 的测试(即 运行 psql 中的一些查询,然后看看发生什么了)。一些注意事项包括:

  • 这可能取决于 Django 为您创建的索引类型
  • 当然,Postgres 在 运行 查询时并不总是使用索引,但如果你有正确的索引和正确的查询(并且如果 运行 中有足够的数据,它应该=46=] 以证明加载索引是合理的)
  • 可能 与 DjangoSELECT 格式化的方式有关

我建议您创建模型并指定您需要索引。然后使用 Django 调试工具栏找出 SELECT 查询真正得到 运行。然后,使用 manage.py dbshel​​l(又名 psql)和 运行 使用相同的 select 分析打开一个 dbshel​​l。假设您可以解释输出,您将亲眼看到您的索引是否发挥作用。如果愿意,请在此处粘贴 ANALYZE 输出。

据此Postgres documentation ORDER BY 可以由 btree 索引辅助。 b-tree 类型的索引是 Django 默认为你创建的。

那么,你为什么不试试这个:

class Meta:
    indexes = [models.Index(fields=['age', 'name'])]

然后在 dbshel​​l 中 运行 一个 EXPLAIN ANALYZE 看看它是否有效。