【问题标题】:Avoiding duplicate DB indexes with Django's unique_together使用 Django 的 unique_together 避免重复的数据库索引
【发布时间】:2015-05-21 08:14:40
【问题描述】:

我有一个项目在 PostgreSQL v9.4 和 Django 1.6 上运行(计划很快升级到 v1.8...)

假设我有以下模型:

class Product(models.Model):
    x = models.ForeignKey(Shop)
    y = models.PositiveIntegerField()
    class Meta:
        unique_together = (("x", "y"), )

据我所知:

  1. 字段 x 是一个外键,所以除非另有要求,Django 会自动为 (x) 添加一个 db 索引
  2. 由于 unique_together 语句,PostgreSQL 隐式生成 (x, y) 的组合索引
  3. 通常,(x, y) 的索引也可以作为 (x) 的索引
  4. 重复索引会在 SQL INSERT 操作中消耗额外的时间

我的结论是,在这种情况下,最好为字段 x 显式声明 db_index=false,以避免重复索引。

这是一个有效的结论吗?

【问题讨论】:

    标签: django postgresql


    【解决方案1】:

    根据documentation,(x, y) 上的索引也将用作针对 x 的查询的索引。由于索引以 x 作为第一列,因此它也比 (y, x) 更有效。所以从这个意义上说你是对的。

    具有多个索引的表将在插入时消耗更多时间,因为将更新更多索引。时间长短取决于表结构。

    最终,这取决于 y 将导致的数据量。如果 y 上有很多变化,则索引大小可能比仅 x 上的索引大很多。在这种情况下,基于此索引的查询将导致从索引加载和处理更多数据。如果变化很小并且索引大小不是很大,那么最好只使用 (x, y) 索引。

    但是,与往常一样,这需要基准测试、基准测试和基准测试。

    数据完整性注意事项

    如果您决定删除 x 上的索引并且仅在 (x, y) 上具有唯一索引,则 x 本身可能包含非唯一值,只要 y 不同。根据实现,这可能很重要,也可能不重要。

    【讨论】:

    • 也许我的解释不够清楚:我确实需要 (x, y) 索引(基准测试也显示了)。问题是关于自动创建的 (x) 索引,因为它是一个外键:明确要求 Django not 创建它是否有意义 (db_index=false)?
    • 是的,我确实明白这一点。这就是为什么它取决于 y 将创建的数据量,因此它需要进行基准测试,或者至少检查真实数据的索引大小。它还影响数据完整性,将其修改为我的答案。
    猜你喜欢
    • 2020-06-19
    • 1970-01-01
    • 2019-02-20
    • 2017-07-10
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多