2015-10-06 43 views
4

說我已經有了與標籤對象的多元關係的圖像對象。我如何限制Django中的prefetch_related?

現在,我正在創建一個搜索視圖來顯示圖像,併爲每個圖像顯示標籤,顯然,要做的事情就是預取圖像的標籤。

但是我每次只顯示15張圖像,但我必須評估整個查詢集以顯示總體結果數。 所以我需要切片之前預取標籤爲第15個元素

如果我預取標籤:

images = watson.filter(queryset, query).prefetch_related('tags') 
amount = images.count() 
images = images[:15] 

這是非常糟糕的,因爲可以有成千上萬的結果和各結果可以有很多標籤。

,但如果我先切片:

images = watson.filter(queryset, query).prefetch_related('tags')[:15] 
amount = images.count() 

現在我只預取15分的結果,這是很好,但是我不能不做另一個查詢統計結果標籤。

如果我這樣做:

images = watson.filter(queryset, query) 
amount = len(images) 
images = images.prefetch_related('tags')[:15] 

我還是最終擊中數據庫兩次,因爲預取做一個新的數據庫查詢。

基本上我需要打一次數據庫獲得的所有圖像,而只預取標籤的第一個15

回答

1

嘗試調用count()第一,然後做prefetch_related()和切片查詢集。

images = watson.filter(queryset, query) 
amount = images.count() 
images = images.prefetch_related('tags')[:15] 

這將執行一個計數查詢,一個查詢前15個圖像,一個查詢標籤。調用count()len()好,因爲它不會獲取不需要的圖像。

+0

本示例將數據庫命中兩次,一次調用count並再次調用prefetch_related時。 – davegri

+0

'count()'導致性能不佳?如果不是,我認爲擔心這是一個過早優化的例子。我不確定是否提取所有結果,並且僅預取前15個將顯着加快;對於大型查詢,調用'count()'比'len()'更有效,因爲queryset沒有加載到內存中。 – Alasdair

+0

因爲我不能僅僅預取15次,所以不得不爲一組圖像命中數據庫。爲什麼這是過早的優化?我期待優化..使用計數,而不是len()是一個有效的更正,但多數民衆贊成在這個問題不是什麼 – davegri