2009-12-28 22 views
10

Bir kasa izleme sistemi hatları boyunca bir şeyleri sürdürmesi gereken bir hizmet yapıyorum. yabancı anahtarların bir çok bu model içine çekilmesi olduğundan ilginç sql sorguları için yapar,Birçok yabancı tuşa sahip modelleri sorgulamada django performansı?

class Incident(models.Model):  
    title = models.CharField(max_length=128) 
    category = models.ForeignKey(Category) 
    status = models.ForeignKey(Status)  
    severity = models.ForeignKey(Severity) 
    owned_by = models.ForeignKey(User, related_name="owned_by", null=True, blank=True) 
    next_action = models.ForeignKey(IncidentAction)  
    created_date = models.DateTimeField() 
    created_by = models.ForeignKey(User, related_name="opened_by")  
    last_edit_date = models.DateTimeField(null=True, blank=True) 
    last_edit_by = models.ForeignKey(User, related_name="last_edit_by", null=True, blank=True)   
    closed_date = models.DateTimeField(null=True, blank=True) 
    closed_by = models.ForeignKey(User, related_name="Closed by", null=True, blank=True) 

: İşte modeli. djblets data grid ve django hata ayıklama araç çubuğunu deneme olarak kullanıyoruz ve yabancı bir anahtar kullanan görünüm için yeni bir sütun eklediğimizde her seferinde vurulmakta olan sorgulama sayısında endişe duyuyoruz, temelde bu tür bir iş akışı iş akışı var :

#prepare the grid 
select * from incident_table; 
#render each row 
for each row in incident table 
    for each column that is a foreign key select row from foreign table with id 

bir yabancı anahtar için bir mülk çekmeye çalışıyor her sütun için sıranın başına ek seçme sorgusu yapar

.

Bunun, django ve ORM ile yabancı anahtar modellerin özelliklerinin ekranda görüntülenmesi ile ilgili evrensel bir sorun olduğunu düşünüyorum. Bir test olarak, veri ızgarasını düşürdüm ve bir queryset için basit bir özellik listesi yaptım ve sorguları benzer şekilde balonun içinde gördüm.

Bunu modele tonlarca kullanıcıyla ölçeklendirmek istiyoruz. Karşılaştırma yaparken, Kullanıcı modeliyle benzer bir görünüm oluşturdum ve tam ekranı yalnızca bir sorgu ile yapıldı, çünkü yalnızca verilen modeldeki alanları alırsanız, ek sütun başına ek bir db vuruşu yapmaz. denedik

Bazı optimizasyonlar vardı:

  • django-orm-cache:
  • django-caching django 1.0.4 ile çalışmak için görünmüyor: Bu önbelleğe alma için iyi çalışır sık ​​sık birlikte modeller
  • görüntüleme düzeyinde önbelleğe alma sorgulanan memcached
  • Edit: select_related() kullanarak, veritabanına geri dönüş yapmadan şablon oluşturma işlemini hızlandırabilir, ancak bu, yabancı anahtarların yalnızca bir Yabancı anahtar başına tek sorgu kullanılarak orijinal sorgudaki zamanın başı. Sadece çoklu veritabanı sorgularını zamanın ilerisine taşıyor gibi görünüyor.

Ama biz kalabalığın bilgelik topluyorsanız bazı derin sorular vardır: yabancı anahtarların ton olan modeller için

İlgili sorular

cevap

11

) (select_related doğru çözümdür; İşinin nasıl olması gerektiği konusunda yanılıyorsun. Hala belirtilen FK genelinde birden fazla sorgu alıyorsanız select_related'i doğru kullanmıyorsunuz. Python oturumun hızlı bir log (Studio sahip bir FK burada django.auth.user için):

>>> from django.db import connection 
>>> studios = Studio.objects.all().select_related('user') 
>>> for studio in studios: 
>>>  print studio.user.email 
>>>   
[email protected] 
[email protected] 
>>> len(connection.queries) 
1 

Yani, (benim test DB 2) Stüdyo nesnelerin listesini var ve her biri için kullanıcı var tek bir SQL sorgusunda. Select_related() çağrısı olmadan, üç sorgu alır.

select_related doesn't handle many-to-many relationships - Ben el ile ara nesnesinden sorgulamaya başlamadan sürece, ekstra sorgu gerektirmeden bu FK'leri takip etmek için m2m ara tabloyu el ile sorgulayabileceğinizi düşünüyorum. Belki seni yakalayan bu mu? Sadece FK ilişkilerini belirlediniz, m2ms değil, bu yüzden basit bir örnek verdim.

+0

Ah, evet. Ben çok düzeltilmiş duruyorum - datagrid aslında sağlanan queryset tarafından sağlanan herhangi bir optimizasyon görmezden geliyor ve kendi aramaları gibi görünüyor. Modelimin örneğinizle bağımsız olarak test edilmesi, select_related() öğesinin yararlarını gün gibi net hale getirdi. Teşekkürler! – dmyung