Django MySQL - Установка индекса для текстового поля
У меня есть база данных статей, по которым я хочу осуществлять поиск. Я использовал обычный Django ORM для поиска, который становился слишком медленным, а затем я узнал немного о Indexes в Django. Я использую MySQL и теперь я знаю, что в MYSQL я не могу поместить индексное поле в TextField, как описано здесь в этом вопросе стека , с которым я столкнулся. Однако в моем случае я не могу изменить это на CharField.
Я читал документацию MyQSL, в которой говорится
MySQL не может индексировать столбцы LONGTEXT, указанные без префикса длины в ключевой части, а префиксная длина не допускается в функциональных ключевые части.
Поскольку я понимал, что поскольку TextField в Django является LONGTEXT для MYSQL, я наткнулся на этот Django-MySQL пакет здесь и подумал, что если я смогу изменить LONGTEXT на MEDIUMTEXT с помощью этого пакета, то проблема может быть решена. Поэтому в моей обновленной модели я сделал следующее
class MyModel(Model):
........
document = SizedTextField(size_class=3)
Однако я все еще вижу ту же ошибку при применении python manage.py makemigrations
django.db.utils.OperationalError: (1170, "BLOB/TEXT колонка 'document' используется в спецификации ключа без длины ключа")
.
Как я могу решить эту проблему?
Все эти родственные типы, TEXT, MEDIUMTEXT и LONGTEXT, слишком велики, чтобы их можно было индексировать без указания префикса. Префикс индекса означает, что в индекс включаются только первые N символов строки. Например, так:
create table mytable (
t text,
index myidx (t(200))
);
В данном примере N равно 200. Таким образом, в индекс попадают только первые 200 символов. Обычно этого достаточно для повышения производительности, если только у вас нет большого количества строк, которые идентичны в первых 200 символах.
Самый длинный префикс, который поддерживает MySQL, зависит от механизма хранения и формата строк. Старые версии MySQL поддерживают индексный префикс длиной до 768 байт, что означает меньшее количество символов в зависимости от того, используете ли вы многобайтовые наборы символов, такие как utf8 или utf8mb4. Последние версии MySQL по умолчанию используют более современный формат строк, который поддерживает до 3072 байт для индекса, опять же уменьшенный на 3 или 4 байта на символ.
Я не постоянный пользователь Django, поэтому я попытался пропустить документацию об определении индексов на классах моделей. Но после нескольких секунд чтения я не вижу возможности объявить префикс для индекса на колонке с длинной строкой.
Я думаю, что ваши варианты - один из следующих:
- Измените столбец на более короткий строковый столбец, который можно индексировать .
- Создайте индекс с помощью клиента MySQL, не используя миграции Django .
возвращает все статьи, которые содержат заданное слово, переданное клиентом. Это будет что-то вроде 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")