2011-04-13 40 views
6

我有一個來自Django ORM查詢的大約1500條記錄的查詢集。我已經使用select_related()和only()方法來確保查詢緊密。我也使用connection.queries來確保只有這一個查詢。也就是說,我已確保在每次迭代中都不會調用額外的查詢。我如何加快Django中的大型數據集的迭代

當我從connection.queries運行查詢剪切和粘貼時,它在0.02秒內運行。然而,迭代這些記錄需要七秒鐘,並且對它們不做任何處理(通過)。

我能做些什麼來加快速度?是什麼導致了這種緩慢?

+0

你應該包括更多關於你的模型和查詢的細節! – 2011-04-13 22:06:33

+4

你也應該寫Django < - 這種方式:)他是一個吉他手,而不是DJ – 2011-04-13 22:10:49

回答

14

當模型對象充滿時,QuerySet會變得非常沉重。在類似的情況下,我使用查詢集上的.values方法來指定我需要的屬性作爲字典列表,這可以快速迭代。 http://docs.djangoproject.com/en/1.3/ref/models/querysets/#values-list

+1

你是對的。事實證明,在每次迭代中模型對象的實例化都會導致很多開銷。使用values方法將設置從7秒迭代到幾毫秒。 – stinkypyper 2011-04-14 15:51:59

+1

太棒了。很高興我能夠提供幫助。 – Brandon 2011-04-14 16:35:17

+0

我注意到了這個巨大的性能提升!我迭代了110000個項目的查詢集,花了近70秒完成。迭代相同的values_list需要5秒鐘! – ninapavlich 2016-08-19 16:57:56

2

1500條記錄遠不是一個大型數據集,而7秒實在太多了。在模型中可能存在一些問題,您可以通過獲取(如Brandon所述)values()查詢,然後通過迭代字典顯式創建1500對象來輕鬆檢查它。只需在構造之前將ValuesQuerySet轉換爲列表來分解數據庫連接。

2

你如何遍歷每個項目:

items = SomeModel.objects.all() 

定期對循環每個

for item in items: 
    print item 

或者使用查詢集iterator

for item in items.iterator(): 
    print item 

根據該文檔時,iterator()可以提高性能。循環非常大的Python列表或字典時同樣適用,最好使用iteritems()

+0

我不確定這是否可行,因爲大部分迭代都是在模板中完成的,我不確定我們是否有.iterator()。 – sprezzatura 2013-04-02 06:25:00

+0

我檢查過它,它實際上工作。加快for循環很多。從0:00:45.550635到0:00:09.761178,至少快4倍! – 2015-05-29 15:23:07

1

您的模型的Meta聲明是否告訴它「排序」一個存儲在其他相關表中的字段?如果是這樣,您嘗試迭代可能會觸發1,500個查詢,因爲Django會跑掉併爲每個項目抓取該字段,然後對它們進行排序。向我們展示您的代碼將幫助我們解決問題!

相關問題