4

У меня проблема с приложением Django. Запросы по модели Scope чрезвычайно медленны, и после некоторой отладки я до сих пор не понял, где проблема.Django Query чрезвычайно медленный

Когда я запрашиваю db как scope = Scope.objects.get(pk='Esoterik I') в django, это занимает 5-10 секунд. База данных содержит менее 10 записей и индекс первичного ключа. поэтому он слишком медленный. При выполнении эквивалентного запроса на db, как SELECT * FROM scope WHERE title='Esoterik I'; все в порядке, оно занимает всего около 50 мс.

Такая же проблема возникает, если я выполняю запрос с набором результатов, например scope_list = Scope.objects.filter(members=some_user), а затем выполняю, например. печать (scope_list) или итерация по элементам списка. Сам запрос занимает всего несколько мс, но отпечаток или итерация элементов повторяются как 5-10 секунд, но набор имеет только две записи.

База данных Backend - Postgresql. Проблема возникает на локальном сервере разработки и apache.

здесь код модели:

class Scope(models.Model): 
    title = models.CharField(primary_key=True, max_length=30) 

    ## the semester the scope is linked with 
    assoc_semester = models.ForeignKey(Semester, null=True) 

    ## the grade of the scope. can be Null if the scope is not a class 
    assoc_grade  = models.ForeignKey(Grade, null=True) 

    ## the timetable of the scope. can be null if the scope is not direct associated with a class 
    assoc_timetable = models.ForeignKey(Timetable, null=True) 

    ## the associated subject of the scope 
    assoc_subject = models.ForeignKey(Subject) 

    ## the calendar of the scope 
    assoc_calendar = models.ForeignKey(Calendar) 

    ## the usergroup of the scope 
    assoc_usergroup = models.ForeignKey(Group) 

    members = models.ManyToManyField(User) 

    unread_count = None 

обновление здесь выход питона профилировщика. кажется, что query.py получило название 1,6 миллиона раз, это слишком много.

+0

У этой модели есть '__unicode __()' метод? не могли бы вы опубликовать его? –

+0

yes it has: 'def __unicode __ (self): return self.title' – 7tupel

+3

Я бы предложил установить [Django Debug Toolbar] (https://github.com/django-debug-toolbar/django-debug-toolbar), чтобы вы можете индивидуально просмотреть каждый запрос. Это даст вам гораздо лучшее представление о том, что замедляет вас. – JcKelley

ответ

2

Вы должны сначала попытаться изолировать проблему. Запустите управляющую оболочку и запустите следующее:

scope = Scope.objects.get(pk='Esoterik I') 
print scope 

Теперь запросы django не выполняются, пока им не очень нужно. То есть, если вы столкнулись с медлительностью после первой строки, проблема заключается в создании запроса, который будет предлагать проблемы с диспетчером объектов. Следующим шагом будет попытка выполнить сырой SQL через django и убедиться, что проблема действительно связана с менеджером, а не с ошибкой в ​​django вообще.

Если вы испытываете медлительность со второй строкой, проблема заключается либо в фактическом выполнении запроса, либо при отображении \ печати данных. Вы можете принудительно выполнить запрос без его распечатки (проверьте документацию), чтобы узнать, какой из них он представляет.

Это, насколько я понимаю, но я думаю, что лучший способ решить это, чтобы сломать процесс вниз к различным частям и выяснить, какая часть является один причиной медлительности

+0

'scope = Scope.objects.get (pk = 'Something')' и 'Scope.objects.get (pk = 'something')' стенд принимает одно и то же время. , если я использую filter() вместо get(), я запускаю проблемы с производительностью при выполнении запроса (например, если я пытаюсь сделать print() с содержимым запроса), поэтому кажется, что запрос правильно построен, но при выполнении время что-то пошло не так – 7tupel

+0

, когда я пытаюсь выполнить необработанный запрос, выполнение занимает то же самое очень долгое время. – 7tupel

1

Для будучи уверенным, что о выполнении базы данных время, то лучше проверить запросы, генерируемые Django, так как Django сгенерированных запросов не может быть простой SELECT * from blah blah

чтобы увидеть Django генерируется запрос:

_somedata = Scope.objects.filter(pk='Esoterik I') # you must use filter in here 
print somedata.query.__format__('') 

Это покажет вам полный запрос, созданный Django. Затем скопируйте его и открыть Postgresql консоль и использовать Postgresql анализ инструменты:

EXPLAIN ANALYZE <your django query here>; 

как:

EXPLAIN ANALYZE SELECT * FROMsomeapp_scope WHERE id = 'Esoterik I'; 

EXPLAIN покажет средние данные исполнения, а ANAYLZE также покажет вам некоторые дополнительные данные о времени выполнения, что анализировать.

Вы также можете узнать, используется ли какой-либо индекс postgresql во время выполнения запроса в этих результатах анализа.

+1

Я пробовал это. необработанный запрос, сделанный django, занимает 26 мс, а простой SELECT * ... занимает 15 мс. поэтому кажется, что сгенерированный sql не является проблемой – 7tupel

Смежные вопросы