2011-08-26 76 views
1

我已經讀過了distinct()API調用有時會遇到一些性能問題。我想嘗試通過orm重寫一個查詢,避免使用不同的(至少配置文件的差異)。Django使用Annotate而不是Distinct()

我的理解是values()在底層執行Group By。但是,當我測試兩種方法時,根據我使用distinct()還是values()/ annotate(),對象的Count是不同的。

zip_codes = Location.objects.values('zip_code').annotate(zip_count=Count('zip_code')).exclude(zip_code=None).count() 

VS.

zip_codes = Location.objects.values_list('zip_code', flat=True).exclude(zip_code=None).distinct() 

這裏有什麼不對嗎?

謝謝!

回答

2

我只是快速檢查您的查詢與我有一個類似的查詢的數據庫。計數是相同的,所以我不確定你的數據是如何導致問題的。

雖然我也很高度懷疑這個前提。 DISTINCT確實是一個cpu密集型查詢。但是,COUNT(*)也是如此,您的第二個查詢將首先運行帶有組的計數聚合,然後對結果運行COUNT。我會把錢放在單一的DISTINCT上,速度更快(我也會檢查你使用的任何數據庫後端)。所有這些與django的ORM幾乎沒有關係,並且與你的數據庫後端有很多關係。

也想一想。與基於註釋的查詢相比,基於不同基礎的查詢在數量上更清晰。你是否有證據支持DISTINCT在你的情況下會變得緩慢,或者更好的是它現在正在形成一個瓶頸?如果不是,那麼你很好地進入了過早優化的範圍,應該重新考慮你的路徑。

Premature Optimization

優化只在重要時才重要。重要的時候,它很重要,但在你知道它很重要之前,不要浪費很多時間去做。即使你知道它很重要,你也需要知道它的重要性。沒有性能數據,你不知道要優化什麼,你可能會優化錯誤的東西。

結果將是晦澀難懂的寫難以調試和難以維護代碼,不能解決您的問題。因此,它具有(a)增加軟件開發和軟件維護成本,以及(b)完全沒有性能效果的雙重缺點。

換句話說,清楚地編寫你的軟件,然後當你發現一個問題追溯到源並修復它。你之前做的任何事情都會適得其反。花你的時間去擔心你的數據庫上哪些索引會起作用,以及在哪裏使用select_related。這些比你在這裏擔心的效率高10000%(除非你一直在計算郵政編碼,在這種情況下,讓我向你介紹緩存)

+0

嘿約翰,我實際上結束了測試distinct()vs.值,註解方法和不同的贏。閱讀起來也很容易。我同意你所說的一切,謝謝。 – Ben

相關問題