我正在使用 Django 创建一些数据库表,如下所示:
class MetadataTerms(models.Model):
    term = models.CharField(max_length=200)
    size = models.IntegerField(default=0)
    validity = models.IntegerField(default=0, choices=TERM_VALIDITY_CHOICES)
然后我运行查找查询以找到正确的行,以term不区分大小写的方式匹配。例如:
MetadataTerms.objects.filter(term__iexact=search_string, size=3)
此查找子句在 SQL 中转换为类似的内容:
 SELECT "app_metadataterms"."id", "app_metadataterms"."term", "app_metadataterms"."size" FROM "app_metadataterms" WHERE (UPPER("app_metadataterms"."term"::text) = UPPER('Jack Nicklaus survives')  AND "app_metadataterms"."size" = 3 );
EXPLAIN在 Postgres 上,我可以对上述内容执行查询,并得到以下查询计划:
                                    QUERY PLAN
-----------------------------------------------------------------------------------
 Seq Scan on app_metadataterms  (cost=0.00..1233.01 rows=118 width=21)
   Filter: ((size = 3) AND (upper((term)::text) = 'JACK NICKLAUS SURVIVES'::text))
因为该term字段没有被索引,并且没有以大小写规范化的方式进行索引,所以上述查询需要对所有数据库行执行慢速 Seq[uential] Scan 操作。
然后我插入一个简单的大小写标准化索引,例如:
 CREATE INDEX size_term_insisitive_idx ON app_metadataterms (upper(term), size);
上面的查询现在运行速度快了大约 6 倍:
                                         QUERY PLAN
---------------------------------------------------------------------------------------------
 Bitmap Heap Scan on app_metadataterms  (cost=5.54..265.15 rows=125 width=21)
   Recheck Cond: ((upper((term)::text) = 'JACK NICKLAUS SURVIVES'::text) AND (size = 3))
   ->  Bitmap Index Scan on size_term_insisitive_idx  (cost=0.00..5.51 rows=125 width=0)
         Index Cond: ((upper((term)::text) = 'JACK NICKLAUS SURVIVES'::text) AND (size = 3))
我的问题是:如何将高级数据库索引的创建注入到 Django 模型管理命令中?