Django Querysets - нужен менее дорогой способ сделать это - PullRequest
0 голосов
/ 15 апреля 2010

У меня проблема с некоторым кодом, и я полагаю , что это связано с расходами набора запросов. Я ищу гораздо менее дорогой (с точки зрения времени) способ этого ...

log.info("Getting Users")
employees = Employee.objects.filter(is_active = True)
log.info("Have Users")

if opt.supervisor:
    if opt.hierarchical:
        people = getSubs(employees, " ".join(args))
    else:
        people = employees.filter(supervisor__name__icontains = " ".join(args))
else:
    log.info("Filtering Users")
    people = employees.filter(name__icontains = " ".join(args)) | \
         employees.filter(unix_accounts__username__icontains = " ".join(args))
    log.info("Filtered Users")

log.info("Processing data")

np = []
for person in people:
    unix, p4, bugz = "No", "No", "No"
    if len(person.unix_accounts.all()): unix = "Yes"
    if len(person.perforce_accounts.all()): p4 = "Yes"
    if len(person.bugzilla_accounts.all()): bugz = "Yes"
    if person.cell_phone != "": exphone = fixphone(person.cell_phone)
    elif person.other_phone != "": exphone = fixphone(person.other_phone)
    else: exphone = ""
    np.append({ 'name':person.name,
                 'office_phone': fixphone(person.office_phone),
                 'position': person.position,
                 'location': person.location.description,
                 'email': person.email,
                 'functional_area': person.functional_area.name,
                 'department': person.department.name,
                 'supervisor': person.supervisor.name,
                 'unix': unix, 'perforce': p4, 'bugzilla':bugz,
                 'cell_phone': fixphone(exphone),
                 'fax': fixphone(person.fax),
                 'last_update': person.last_update.ctime() })

log.info("Have data")

Теперь это приводит к журналу, который выглядит следующим образом ..

19:00:55 INFO     phone       phone Getting Users
19:00:57 INFO     phone       phone Have Users
19:00:57 INFO     phone       phone Processing data
19:01:30 INFO     phone       phone Have data

Как видите, для перебора данных требуется более 30 секунд. Это слишком дорого. Может кто-нибудь подсказать мне более эффективный способ сделать это. Я думал, что если бы я сделал первый фильтр, который бы упростил ситуацию, но, похоже, не дал никакого эффекта. Я в растерянности от этого.

Спасибо

Для ясности, это около 1500 сотрудников - не слишком много !!

1 Ответ

3 голосов
/ 15 апреля 2010
  1. Или Q объектов вместе вместо QuerySet с.
  2. QuerySet.select_related()
  3. QuerySet.iterator()
  4. Используйте QuerySet.extra() для добавления IS NULL полей вместо трех len() вызовов в цикле.
...