Django MySQL - 在文本字段上设置索引

Django MySQL - Setting an index on a Textfield

我有一个要搜索的文章数据库。我一直在使用普通的 Django ORM 进行搜索,速度越来越慢,然后我对 Django 中的 Indexes 有了一些了解。我正在使用 MySQL,我现在知道使用 MYSQL 我无法将索引字段放入 TextField 中,正如我所面对的 here in this stack question 所描述的那样。但是就我而言,我无法将其更改为 CharField.

我正在阅读 MyQSL 文档,其中说明

MySQL cannot index LONGTEXT columns specified without a prefix length on the key part, and prefix lengths are not permitted in functional key parts.

因此我的理解是,由于 Django 中的 TextField 是 MYSQL 的 LONGTEXT,我遇到了这个 Django-MySQL package here 并认为如果我可以使用此包将 LONGTEXT 更改为 MEDIUMTEXT,则可以使用它,这可能会得到解决。所以我更新的模型是这样做的

class MyModel(Model):
    ........
    document = SizedTextField(size_class=3)

但是,我在应用 python manage.py makemigrations

时仍然看到同样的错误

django.db.utils.OperationalError: (1170, "BLOB/TEXT column 'document' used in key specification without a key length")

我该如何解决这个问题?

所有这些相关类型 TEXTMEDIUMTEXTLONGTEXT 都太大而无法在不指定前缀的情况下进行索引。索引前缀意味着只有字符串的前 N ​​个字符包含在索引中。像这样:

create table mytable (
  t text, 
  index myidx (t(200))
);

本例中的前缀长度为200个字符。因此只有前 200 个字符包含在索引中。通常这足以提高性能,除非您有大量前 200 个字符相同的字符串。

MySQL 支持的最长前缀取决于存储引擎和行格式。 MySQL 的旧版本支持最多 768 字节的索引前缀,这意味着较少的字符数,具体取决于您是否使用 multi-byte 字符集,如 utf8 或 utf8mb4。 MySQL 的最新版本默认为更现代的行格式,支持最多 3072 字节的索引,同样减少了每个字符 3 或 4 个字节。

我不是 Django 的普通用户,所以我试图浏览 documentation 关于在模型 类 上定义索引的内容。但是经过几秒钟的阅读,我没有看到为长字符串列上的索引声明前缀的选项。

我认为您的选择是以下之一:

  • 将该列更改为可以索引的较短的字符串列
  • 使用 MySQL 客户端创建索引,不使用 Django 迁移

returning all the articles that contain a given word passed by the client. So would be something SELECT * from articles WHERE text CONTAINS searchword

添加

FULLTEXT(text)

并使用

WHERE MATCH(text) AGAINST("searchword")

或者

WHERE MATCH(text) AGAINST("+searchword" IN BOOLEAN MODE)

它将 运行 非常快。有一些注意事项——短词和“停止”词(如“the”)将被忽略。

(如果 DJango 无法做到这一点,那么您必须使用“原始 SQL”来完成。)