Vraag Django hooiberg whoosh super langzaam


Ik heb een eenvoudige setup met django-haystack en whoosh-engine. Een zoekopdracht met 19 objecten kostte me 8 seconden. Ik gebruikte de django-debug-toolbar om vast te stellen dat ik een hoop herhaalde query's had.

Vervolgens heb ik mijn zoekweergave bijgewerkt naar prefetch-relaties, zodat dubbele zoekopdrachten niet zouden plaatsvinden:

class MySearchView(SearchView):
    template_name = 'search_results.html'
    form_class = SearchForm
    queryset = RelatedSearchQuerySet().load_all().load_all_queryset(
        models.Customer, models.Customer.objects.all().select_related('customer_number').prefetch_related(
            'keywords'
        )
    ).load_all_queryset(
        models.Contact, models.Contact.objects.all().select_related('customer')
    ).load_all_queryset(
        models.Account, models.Account.objects.all().select_related(
            'customer', 'account_number', 'main_contact', 'main_contact__customer'
        )
    ).load_all_queryset(
        models.Invoice, models.Invoice.objects.all().select_related(
            'customer', 'end_customer', 'customer__original', 'end_customer__original', 'quote_number', 'invoice_number'
        )
    ).load_all_queryset(
        models.File, models.File.objects.all().select_related('file_number', 'customer').prefetch_related(
            'keywords'
        )
    ).load_all_queryset(
        models.Import, models.Import.objects.all().select_related('import_number', 'customer').prefetch_related(
            'keywords'
        )
    ).load_all_queryset(
        models.Event, models.Event.objects.all().prefetch_related('customers', 'contracts', 'accounts', 'keywords')
    )

Maar zelfs dan duurt de zoekactie nog steeds 5 seconden. Ik heb toen de profiler gebruikt django-debug-toolbar, die mij deze informatie gaf:

Django debug toolbar profiler results

Van wat ik kan vertellen, ligt het probleem haystack/query:779::__getitem__, die twee keer wordt geraakt, elk kost 1,5 seconden. Ik heb de code in kwestie doorgenomen, maar kan er geen betekenis aan geven. Dus waar ga ik heen vanaf hier?


13
2017-08-24 13:16


oorsprong


antwoorden:


U zegt in de vraag:

Vervolgens heb ik mijn zoekweergave bijgewerkt naar prefetch-relaties [...]

De code die u gebruikt, wordt echter niet gebruikt QuerySet.prefetch_related voor de meesten van hen. In plaats daarvan gebruikt uw voorbeeldcode QuerySet.select_related voor de meesten; hiermee worden de objecten niet vooraf opgehaald.

De documentatie voor elk van deze methoden is uitgebreid en kan helpen om te beslissen wat correct is voor uw geval.

Met name, de QuerySet.prefetch_related documentatie zegt:

select_related werkt door een SQL-join te maken en de velden van het gerelateerde object op te nemen in de SELECT uitspraak. Om deze reden haalt select_related de gerelateerde objecten in dezelfde databasequery. Om echter de veel grotere resultaatset te vermijden die zou voortvloeien uit het samenvoegen van een 'veel' relatie, select_related is beperkt tot relaties met één waarde - foreign key en one-to-one.

prefetch_related, aan de andere kant, doet een afzonderlijke opzoeking voor elke relatie, en doet het 'meedoen' in Python. Hierdoor kan het vooraf veel-op-veel en veel-op-één-objecten vooraf ophalen, wat niet kan worden gedaan met select_related, naast de foreign key en één-op-één relaties die worden ondersteund door select_related. Het ondersteunt ook prefetching van GenericRelation en GenericForeignKeyhet moet echter worden beperkt tot een homogene reeks resultaten. Bijvoorbeeld prefetching-objecten waarnaar wordt verwezen door a GenericForeignKey wordt alleen ondersteund als de query beperkt is tot één ContentType.


1
2017-11-14 02:54