Django Фильтры значков фильтра медленные на TextField () - PullRequest
0 голосов
/ 13 января 2020
response_title = models.TextField(null=True,blank=True)
response_status_code = models.IntegerField(null=True,blank=True)
response_body = models.TextField(null=True,blank=True)

недавно я столкнулся с низкой производительностью своего сайта, так что вот мое наблюдение из оболочки Django, у меня 32 000 записей в моей модели, и выполнение с icontains медленное по сравнению с contains также count на icontains запрос занял 4 секунды, тогда как count на contain занял 0,3 секунды.

тип данных, которые я храню в response_body - это необработанное тело ответа.

from .models import Response_Dataset

>>> Response_Dataset.objects.count() ## 0.1 sec
32289

>> Response_Dataset.objects.filter(response_body__icontains='hack') ## 0.4 seconds

>>> x = Response_Dataset.objects.filter(response_body__icontains='hack')
>>> x.count() ### 4 seconds
65

>>> x = Response_Dataset.objects.filter(response_body__contains='a') ### 0.2 seconds
>>> x.count() ### 0.3 seconds
23857 

Выполнение с icontains в любом другом поле, кроме response_body, чрезвычайно быстро, например, на response_title или response_status_code

1 Ответ

1 голос
/ 15 января 2020
  1. Вам необходимо знать, когда Django Queryset действительно получает свои результаты из базы данных. Django ORM не обращается к базе данных, пока вам действительно не понадобится значение. Он подробно описан в документации Django .

    . Внутри QuerySet может быть сконструирован, отфильтрован, разрезан и, как правило, передан без фактического попадания в базу данных. На самом деле никаких действий с базой данных не происходит, пока вы не сделаете что-то для оценки набора запросов.

from .models import Response_Dataset

>>> Response_Dataset.objects.count()  # ==> Database Hit
32289

>>> x = Response_Dataset.objects.filter(response_body__icontains='hack') # ==> Doesn't hit
>>> x.count() # ==> Hit
65

>>> x = Response_Dataset.objects.filter(response_body__contains='a') # ==> Doesn't hit
>>> x.count() # ==> Hit
23857 

Если некоторые операторы SQL работают медленно, необходимо взглянуть на операторы EXPLAIN SELECT в базе данных и установить индекс соответствующим образом. Вы можете установить панель инструментов отладки Django и использовать команду debugsqlshell для просмотра SQL, запрошенного базой данных. Метод оптимизации зависит от используемой вами СУБД.

По моему мнению, если вы хотите выполнить полнотекстовый поиск по действительно большому набору данных, поисковая система, подобная ElasticSearch, правильный выбор.

...