如何提高以下查询的效果?
class Worker(models.Model):
name = models.CharField(max_length=32, db_index=True)
# This line is slow:
Worker.objects.filter(name__startswith='John')
我已经为模型添加了索引,但是......它根本就没用过。 然而,当我在没有startswith
的情况下进行普通过滤时,索引会启动:
# This line is fast:
Worker.objects.filter(name='John')
为什么索引不与startswith
一起使用?
答案 0 :(得分:4)
问题是startswith
表达式转换为包含LIKE
运算符的SQL查询,该运算符不利用默认索引。
解决方案:使用特殊operator class添加其他索引:
CREATE INDEX "appname_model_field_like_idx"
ON "appname_model" ("fieldname" varchar_pattern_ops);
一步一步:
首先,创建一个空迁移:
python3 manage.py makemigrations appName --empty
添加自定义RunSQL命令:
class Migration(migrations.Migration):
dependencies = [
('stats', '0002_auto_2010213_0159.py'),
]
operations = [
migrations.RunSQL(
sql=r'''CREATE INDEX "appname_model_field_like_idx"
ON "appname_model" ("fieldname" varchar_pattern_ops);''',
reverse_sql=r'DROP INDEX "appname_model_field_like_idx";'
),
]
答案 1 :(得分:0)
如果您的后端是MySQL,请尝试使用不区分大小写的istartswith
来使用索引:
Worker.objects.filter(name__istartswith='John')