如何提高以下查询的性能?

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 一起使用?

最佳答案

问题是 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";'
            ),
        ]
    
  • 关于python - Django — 提高 `startswith` 性能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49682773/

    10-13 03:22