2011-03-24 1 views
11

N + 1에 관한 피어 (peer)와 나쁜 DB 쿼리의 심각한 성능 영향에 대해 이야기 한 후 http://guides.rubyonrails.org/active_record_querying.html을 방문했습니다.Django N + 1 쿼리 솔루션

액티브 (레일) :

clients = Client.includes(:address).limit(10) 
클라이언트의 주소를 가지고 있고, 나는 클라이언트를 통해 반복, 레일이 가서 쿼리에 추가 알려 includes를 제공하는 반면에 액세스하려는

, 박쥐에서 9 개의 쿼리가 제거됩니다.

장고 :

https://github.com/lilspikey/django-batch-select 배치 쿼리 지원을 제공합니다. Rails가 제공하는 것을 달성하기 위해 다른 라이브러리 나 트릭을 알고 있습니까? (예 : 19 개 문자로 N + 1을 수정하고 매우 명확한 레일 예제 에서처럼) 또한 배치 선택은 같은 방식으로 문제를 해결합니까, 아니면이 두 가지 다른 것입니까?

나는 언뜻 보면 대답 일지 모르지만, select_related에 대해 묻지 않습니다. 나는 addressclient에 forign 키가있는 상황에 대해 말하고 있습니다.

답변

9

불행히도 Django의 ORM은 아직 수행 할 방법이 없습니다.

다행히도, 파이썬에서 약간의 작업만으로 2 개의 쿼리만으로도 가능합니다.

clients = list(Client.objects.all()[:10]) 
addresses = dict((x.client_id, x) for x in 
    Address.objects.filter(client__in=clients)) 
for client in clients: 
    print client, addresses[client.id] 
+0

감사합니다. BTW는 쿼리의 효율성을 높여 줄 것입니다 (즉, 레일스는 더 나은 성능을 제공하는 마법 같은 것을 할 것인가? 아니면 동일한 것의 구문 설탕 일까?). 분명히 모든 것이 즉시 메모리로 평가 될 필요가 없다면 더 좋을 것입니다. 그러나 아마도 그것들도 그렇게 할 것입니다. – orokusaki

+0

잘 모르겠습니다. 하나의 쿼리에서 액션을 수행 할 수는 있지만 장고의 ORM이 아직 가지고 있지 않은 수준의 속임수가 필요합니다. –

+0

좋습니다. 다시 한번 감사드립니다. – orokusaki

2

django-batch-select이 문제에 대한 답변을 제공하기로되어 있습니다. 위의 Ignacio의 대답은 나에게 가장 좋은 것으로 보인다.