次のように、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 );
Postgres ではEXPLAIN
、上記に対してクエリを実行でき、次のクエリ プランが得られます。
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
、上記のクエリでは、すべてのデータベース行に対して低速の Sequential 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))
私の質問は、高度な DB インデックスの作成を Django モデル管理コマンドに挿入するにはどうすればよいですか?