我有一個簡單的數據庫約3900條目,並使用通用視圖(django.views.generic.list_detail.object_list)與其Django的分頁(通過paginate_by)瀏覽數據庫中的數據,但有些查詢速度很慢。Django Paginate CPU時間縮放與所選對象的數量不顯示對象
奇怪的是,儘管每頁僅顯示50個對象,但渲染時間與選擇多少個對象大致呈線性關係(並且我不對對象進行任何排序)。例如,如果我使用〜3900,〜1800,〜900,〜54選擇的對象進行查詢,它將分別花費〜8500 ms,〜4000 ms,〜2500 ms,〜800 ms CPU時間(使用django-debug-toolbar)而SQL只需要約50毫秒,約40毫秒,約35毫秒,約30毫秒,而所有頁面恰好有50個對象。按照django optimization page中的建議,我已經使用select_related減少了SQL查詢的數量。
使用profiling middleware絕大多數長的查詢時間都花在做數據庫的東西:
735924 function calls (702255 primitive calls) in 11.950 CPU seconds
Ordered by: internal time, call count
ncalls tottime percall cumtime percall filename:lineno(function)
35546/3976 4.118 0.000 9.585 0.002 /usr/local/lib/python2.6/dist-packages/django/db/models/query.py:1120(get_cached_row)
30174 3.589 0.000 3.991 0.000 /usr/local/lib/python2.6/dist-packages/django/db/models/base.py:250(__init__)
---- By file ----
tottime
47.0% 3.669 /usr/local/lib/python2.6/dist-packages/django/db/models/base.py
7.7% 0.601 /usr/local/lib/python2.6/dist-packages/django/db/models/options.py
6.8% 0.531 /usr/local/lib/python2.6/dist-packages/django/db/models/query_utils.py
6.6% 0.519 /usr/local/lib/python2.6/dist-packages/django/db/backends/sqlite3/base.py
6.4% 0.496 /usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py
5.0% 0.387 /usr/local/lib/python2.6/dist-packages/django/db/models/fields/__init__.py
3.1% 0.244 /usr/local/lib/python2.6/dist-packages/django/db/backends/util.py
2.9% 0.225 /usr/local/lib/python2.6/dist-packages/django/db/backends/__init__.py
2.7% 0.213 /usr/local/lib/python2.6/dist-packages/django/db/models/query.py
2.2% 0.171 /usr/local/lib/python2.6/dist-packages/django/dispatch/dispatcher.py
1.7% 0.136 /usr/local/lib/python2.6/dist-packages/django/template/__init__.py
1.7% 0.131 /usr/local/lib/python2.6/dist-packages/django/utils/datastructures.py
1.1% 0.088 /usr/lib/python2.6/posixpath.py
0.8% 0.066 /usr/local/lib/python2.6/dist-packages/django/db/utils.py
...
---- By group ---
tottime
89.5% 6.988 /usr/local/lib/python2.6/dist-packages/django/db
3.6% 0.279 /usr/local/lib/python2.6/dist-packages/django/utils
...
我可以理解爲什麼SQL查詢可與所選條目的數量規模。不過,我不明白爲什麼剩下的CPU時間應該受到影響。這非常違反直覺,我想知道是否有任何調試/分析技巧可以幫助我。
在sqlite,python2.6,apache2-prefork中使用django-1.2.3(儘管切換到mpm-worker並沒有明顯的改變)。任何提示/技巧將不勝感激。內存使用似乎並不是一個因素(機器有2Gb RAM和免費說只使用300Mb(另外600Mb的緩存)),並且數據庫與機器在同一臺服務器上。
發現我的錯誤。我發現我的錯誤。我檢查了原始查詢集的長度,看它是否是長度爲1(如果是的話,然後轉到object_detail)。這導致評估完整的查詢集(根據django-debug-toolbar,它仍然只用了5ms),但是顯着減緩了所有查詢集。
基本上沒有像一些愚蠢的事:
if len(queryset) == 1:
return HttpResponseRedirect(fwd to object_detail url ...)
return object_list(request, queryset=queryset, paginate_by= ...)
評價的結果,全面查詢;而不是分頁查詢。
你有在你的sqlite數據庫設置索引嗎?否則,sqlite可能會進行線性掃描以進行過濾或排序。 – 2010-11-01 18:54:44
我目前沒有設置任何索引;但是我並沒有對結果進行排序,而且我的印象是django-debug-toolbar使用SQL查詢。因此,如果SQL查詢總共需要50毫秒來選擇〜3900個對象的1-50個參數,並且選擇約50個對象的1-50個參數需要30毫秒,CPU時間差應該只有20毫秒,而不是7800毫秒的當前差異。 – 2010-11-01 19:19:00