2017-09-26 53 views
0

我一直在教自己的Django和SQL,我注意到的一件事是,當處理大型表(> 1,000,000條記錄)時,指定一個排序非常緩慢。例如:數據庫查詢:Django的快速替代方法order_by()

Model.objects()[offset:limit]

可能需要幾毫秒的時間,假設offsetlimit是一個足夠小的範圍內。但是:

Model.objects()[offset:limit].order_by('name')

可能需要10或20秒,取決於表中的行的數目。我明白爲什麼會這樣;必須檢查所有行以確保返回正確的結果。我也明白,這更多的是SQL問題,而不是Django問題,我用Django代碼解釋它更容易。

所以這是我的問題:

  1. 因爲我看到Django的生產網站顯示下令從非常大的表中的數據,他們是如何做到這一點,而不每個查詢回吐>10秒?

  2. 我解決了第一個問題後,如何擴展我的Django應用程序以允許多列(名稱,日期,值等)的排序?

我的直覺說,回答第一個問題是插入我希望它顯示,這樣在執行查詢時沒有順序是必要的順序每個記錄,但似乎難以維持。

此外,這意味着,唯一的答案我能想到的第二個問題涉及創建多個表,均有不同的列排序,然後訪問它像這樣:

if request.GET['order'] == name: 
    result_set = NameOrderedModel.objects()[offset:limit] 
elif request.GET['order'] == value: 
    result_set = ValueOrderedModel.objects()[offset:limit] 

的代碼,這些查詢是相當簡單的,但我不寒而慄,想到要建立一個數據庫需要多少工作,以便這樣的查詢是可能的。有沒有更好的辦法?

+0

您是否嘗試在Django ORM中編寫原始SQL查詢?這可以提高您的查詢性能多倍。而抵消,限制和order_by肯定會快得多。 –

+1

這個問題很可能是(缺乏)索引。只需在'name'字段中添加'db_index = True'並且'migrate'來查看是否有幫助。 – Selcuk

回答

1

是的,不應該那麼慢。嘗試將一個索引添加到「名稱」列。這絕對應該回到毫秒範圍內。對於那麼多行,應該預期一個索引。

很少有其他建議:ORDER_BY後限制,像這樣:

1)爲了提高可讀性,我會做偏移

Model.objects.all().order_by('name')[offset:limit] 

2)如果你仍然有速度問題,打印執行SQL語句:

data = Model.objects.all().order_by('name')[offset:limit] 
print data.query 

並在查詢工具中執行一些故障排除,或者如果您仍然卡住,請嘗試粘貼回來。