【问题标题】:Improve performance of Django PostgreSQL query提高 Django PostgreSQL 查询的性能
【发布时间】:2017-11-23 10:55:18
【问题描述】:

假设我有下表:

class Word(Model):
    id = UUIDField(primary_key=True,
                   default=uuid.uuid4,
                   editable=False)
    name = CharField(_('Word'),
                     db_index=True,
                     max_length=250)

此表包含大约 300 万行。内容主要是西里尔文字。

我想要完成的是搜索一些预定义的值列表。问题是表中的单词有重音。

表格内容如下:

мо́рква
буря́к
я́блуко

但我查询时没有重音。

words = ['морква', 'буряк', 'яблуко']

Word.objects.annotated(name_without_accent=Func(
            F('name'),Value('[%s]' % ACCENTS), Value(''),
            function='regexp_replace',
        )).filter(reduce(operator.or_, [Q(name_without_accent__icontains=w) for w in words], Q()))

问题是对这么大的表的查询运行时间很长。 words 列表可以包含更多元素(大约 20-30 个)。

有没有办法提高查询这么大表的整体性能? 改进 Django 查询?调整 Postgres?使用一些外部工具?

【问题讨论】:

    标签: django postgresql django-models


    【解决方案1】:

    尝试使用unicodedata.normalize('NFD', word) 而不是正则表达式。如果您进行大量此类查询,则使用非重音版本的单词创建附加字段并按该字段创建索引是合理的,因为在您的情况下 db_index 没有提供任何帮助,它只会通过重新索引减慢表。

    【讨论】:

    • 我应该在哪里使用unicodedata.normalize('NFD', word)?
    • 在注释字段中
    • 忘记了我之前关于注释的评论(((早上回答太早了,对不起(((我认为最好的解决方案是创建额外的字段甚至额外的临时表)
    • 好的。非常感谢。
    • 照你说的做了,但contains 仍然很慢。我该如何改进它?查询运行 7 秒(而不是之前的 65 秒)。
    猜你喜欢
    • 2021-08-03
    • 2013-02-17
    • 1970-01-01
    • 2015-07-11
    • 2012-01-28
    • 2018-10-19
    • 2021-07-30
    • 2022-01-08
    • 1970-01-01
    相关资源
    最近更新 更多