2015-08-24 15 views
13

Ben django-haystack ve whoosh motoru ile basit bir kurulum var. 19 nesne üreten bir arama 8 saniye sürdü. Tekrarlanan sorguların bir demetinin olduğunu belirlemek için django-debug-toolbar'ı kullandım.Django haystack whoosh süper yavaş

o sorgular olmayacaktı yinelenen bu yüzden daha sonra önceden getirir ilişkilerine benim arama görünümünü güncelleme:

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') 
    ) 

Ancak bu durumda bile arama hala 5 saniye sürer. Söyleyebileceğim kadarıyla

Django debug toolbar profiler results

, konu haystack/query:779::__getitem__ yatıyor, her 1.5 saniyede bir mal, iki kez isabet: Sonra bana bu bilgiyi verdi, django-debug-toolbar gelen profilleyiciyi kullandı. Söz konusu kodun içine baktım, ancak anlam ifade edemiyorum. Peki buradan nereye giderim?

+2

Arama indeksinizde kaç tane nesne var? – phildini

+0

@phildini "19 nesne" –

+2

'__getitem__' veritabanına 2 sorgu tetikler gibi görünüyor. '_fill_cache'ye bir göz atın, genel olarak yaklaşık 3 saniye süren iki kez get_results’u çağırır. Tüm öğelerin veritabanından önceden getirildiğinden emin misiniz? –

cevap

1

Söz konusu ki:

Sonra önceden getirme ilişkilerine benim arama görünümünü güncellenen [...]

Eğer mevcut kod olsa, çoğu için QuerySet.prefetch_related kullanmaz. Bunun yerine, örnek kodunuz çoğu için QuerySet.select_related kullanır; Bu, nesneleri önceden getirmez.

Bu yöntemlerin her birinin belgeleri kapsamlıdır ve durumunuz için hangisinin doğru olduğuna karar vermenize yardımcı olabilir.

Özellikle, the QuerySet.prefetch_related documentation diyor: Bir SQL katılmak oluşturma ve SELECT açıklamada, ilgili nesnenin alanlar dahil ederek

select_related çalışır. Bu nedenle select_related, ilgili nesneleri aynı veritabanı sorgusunda alır. Bununla birlikte, "çok" bir ilişkiye girmekten kaynaklanan daha büyük sonuç kümesini önlemek için, select_related tek değerli ilişkilerle sınırlıdır - yabancı anahtar ve bire bir. Diğer yandan, her bir ilişki için ayrı bir arama yapar ve Python'da "birleştirmeyi" yapar. Bu, select_related tarafından desteklenen yabancı anahtar ve bire bir ilişkilere ek olarak, select_related kullanılarak yapılamayan çoktan çoğa ve çoktan nesnelere önceden izin verir. Aynı zamanda GenericRelation ve GenericForeignKey'un ön yüklemesini destekler, ancak homojen bir sonuç kümesiyle sınırlandırılmalıdır. Örneğin, GenericForeignKey tarafından başvurulan nesnelerin önceden getirilmesi yalnızca sorgu bir ContentType ile sınırlandırılmışsa desteklenir.