Bil*_*one 12 database django indexing model django-models
我正在使用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)
Run Code Online (Sandbox Code Playgroud)
然后我运行查询查询,以term不区分大小写的方式找到正确匹配的相应行.例如:
MetadataTerms.objects.filter(term__iexact=search_string, size=3)
Run Code Online (Sandbox Code Playgroud)
这个查找子句转换为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 );
Run Code Online (Sandbox Code Playgroud)
在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))
Run Code Online (Sandbox Code Playgroud)
由于该term字段未编制索引,并且未按案例规范化方式编制索引,因此上述查询需要跨所有数据库行执行慢速Seq [uential] Scan操作.
然后我插入一个简单的case-normalized索引,例如:
CREATE INDEX size_term_insisitive_idx ON app_metadataterms (upper(term), size);
Run Code Online (Sandbox Code Playgroud)
上面的查询现在运行速度提高了大约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))
Run Code Online (Sandbox Code Playgroud)
我的问题是:如何在Django模型管理命令中注入高级DB索引的创建?
Max*_*ysh 12
Django 1.11(2.0也应该没问题)+ PostgreSQL:
首先,创建一个空迁移:
python3 manage.py makemigrations appName --empty
Run Code Online (Sandbox Code Playgroud)Django UPPER用于不精确的查找.因此,创建一个用于添加UPPER(yourField)索引的迁移:
# -*- coding: utf-8 -*-
# Generated by Django 1.11.7 on 2017-12-14 23:11
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('stats', '0027_remove_siteuser_is_admin'),
]
operations = [
migrations.RunSQL(
sql=r'CREATE INDEX "stats_siteuser_upper_idx" ON "stats_siteuser" (UPPER("email"));',
reverse_sql=r'DROP INDEX "stats_siteuser_upper_idx";'
),
]
Run Code Online (Sandbox Code Playgroud)Tom*_*cik 10
从3.2开始,您可以添加*expressions到Index.
如果你想创建
CREATE INDEX size_term_insisitive_idx ON app_metadataterms (upper(term), size);
Run Code Online (Sandbox Code Playgroud)
类似的东西应该有效。
from django.db.models import Index
from django.db.models.functions import Upper
class MetadataTerms(models.Model):
term = models.CharField(max_length=200)
size = models.IntegerField(default=0)
validity = models.IntegerField(default=0, choices=TERM_VALIDITY_CHOICES)
class Meta:
indexes = [
Index(
Upper('term'), 'size',
name='size_term_insisitive_idx',
),
]
Run Code Online (Sandbox Code Playgroud)
要将自定义 sql 注入 django 模型管理命令,请查看django-admin.py sqlcustom
\n\n您可以将包含创建索引的 sql 文件放入<app_name>/sql/<model_name>.sql
从应用它们时的文档来看:
\n\n\n\n\n执行完所有 models\xe2\x80\x99 表创建语句后,SQL 文件将直接通过管道传输到数据库中。使用此 SQL 挂钩进行任何表修改,或将任何 SQL 函数插入数据库。
\n
您可以通过运行查看每个应用程序的自定义 sqlmanage.py sqlcustom <app_name>
| 归档时间: |
|
| 查看次数: |
1974 次 |
| 最近记录: |