0

postgres には時間がかかると思っていましたが、ここでボトルネックにならないとは思っていませんでした。どうすればこれを解決できますか?

2772856 function calls (2578490 primitive calls) in 32.361 seconds

Ordered by: internal time

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
127921/19340    3.670    0.000   11.486    0.001 /usr/lib/python2.7/copy.py:145(deepcopy)
 2240    3.031    0.001    3.244    0.001 {method 'execute' of 'psycopg2._psycopg.cursor' objects}
114402    1.541    0.000    2.348    0.000 /usr/lib/python2.7/copy.py:267(_keep_alive)

-------------------------------------------------- --------------------------------

    suppliers = models.Supplier.objects.all().order_by('company')
    for supplier in suppliers :
        sup = {}
        sup['company'] = supplier.company
        sup['supplies'] = get_supplies(1, supplier.uuid)
        sup['category'] = 'Supplier'
        if isocode == None :
            addresses = models.Address.objects.filter(company = supplier.company)
        else :
            addresses = models.Address.objects.filter(company = supplier.company, country_iso = isocode)
        sup['contacts'] = models.Contact.objects.filter(address__in=addresses)
        company_list.append(sup)

-------------------------------------------------- --------------------------------

def get_supplies (bought_in_controlpanel_id, supplier_uuid) :

    supplier    = None
    activenode  = None

    if supplier_uuid is not None :
        supplier = models.Supplier.objects.get(uuid = supplier_uuid)

    try :
        activenode = boughtin.BoughtInControlPanel.objects.get (pk = 1)
    except :
        pass

    supplies = boughtin.BoughtInControlPanel.objects.filter (parent = activenode)
    for supply in supplies :
        supply.checked  = 0
        supply.disabled = ""
        supply.open     = 0

        if supplier_uuid is not None :
            try    :
                models.Supplies.objects.get(supplier = supplier, bought_in_control_panel = supply)
                supply.checked = 1
            except :
                supply.open    = 1

    return supplies
4

1 に答える 1

3

ループ内で DB にクエリを実行すると、通常、パフォーマンスが低下します。それを避けてみてください。

リレーションと__inクエリを使い続けてみませんか? =)

最初の例では、これはより少ない SQL クエリで動作するはずだと思います。

company_list = models.Supplier.objects.values_list('company', flat=True)

filter_kwargs = dict(address__company__in=company_list)

if isocode is not None:
    filter_kwargs.update(dict(address__company__isocode=isocode))

sup['contacts'] = models.Contact.objects.filter(**filter_kwargs)

に関しては、数回ヒットすることが確実でない限り、ループ内もget_supplies()避けSupplies.objects.get()ます。ループの前に 1 つの大きなクエリを使用して消耗品のリストを収集し、そのリストに必要なアイテムが存在するかどうかを確認することをお勧めします。ただし、両方のバリアントをプロファイリングして、より高速な方を選択する必要があります。

于 2012-07-09T12:10:36.787 に答える