假设我有一个类似的模型
class Widget(models.Model):
a = models.CharField(db_index=True, unique=True)
b = models.CharField()
然后我执行一个类似的过滤器
Widgets.objects.filter(a=a, b=b).get()
你是否期望这方面的表现(1(相同;或者(2(更糟?-如果模型被定义为:
class Widget(models.Model):
a = models.CharField(db_index=True, unique=True)
b = models.CharField(db_index=True) # <--- now b is indexed
我的意思是,从逻辑上讲,因为a
是索引的并且是唯一的,所以最多可以为a的某个值找到一个结果,所以引擎可以只在a上进行查找,然后检查结果b字段是否为预期值,而不在b
上使用任何索引。
但在实践中,生成的SQL和底层SQL引擎在查询规划方面是否足够聪明,能够解决这一问题?这样的查询规划是琐碎的吗?
并不是说索引本身就是使用的。数据库会收集有关指数特异性的统计数据,有时全扫描更有效。例如,如果数据库期望返回很大一部分元素。在这种情况下,它将执行磁盘I/O以返回记录,因此首先使用索引可能会较慢。
您是否期望此操作的性能(1(相同;或者(2(更糟?
大致相同,或者稍差。以防索引这两个字段。数据库通常会查找最能加速的字段的索引。b
可能对此更好,因此它将使用b
的索引,并且";扫描";对于CCD_ 5的字段。
但是,您可以同时索引和。您可以使用Meta
选项[Django-doc]的indexes
选择[Django/doc]:
class Widget(models.Model):
a = models.CharField(db_index=True, unique=True)
b = models.CharField(db_index=True)
class Meta:
indexes = [
models.Index(fields=['a', 'b'])# ← index together
]
也就是说,如果a
(或b
(已经可以显著减少搜索空间,则加速不会那么多。索引用于仅检索数据库所需的磁盘的这些部分。然而,如果第二个索引减少了元素的数量,但它仍然需要或多或少相同的段,则速度不会那么快,因为I/O(非常(经常是瓶颈。