电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Django程序的優化技巧

瀏覽:2日期:2024-09-08 17:56:33
友情提示:

過度性能優化是沒有必要甚至有害的,因為花大力氣帶來的毫秒級的響應提升你的用戶可能根本感知不到,畢竟開發人員的時間也很寶貴。

性能優化指標

在對一個Web項目進行性能優化時,我們通常需要評價多個指標:

響應時間 最大并發連接數 代碼的行數 函數調用次數 內存占用情況 CPU占比

其中響應時間(服務器從接收用戶請求,處理該請求并返回結果所需的總的時間)通常是最重要的指標,因為過長的響應時間會讓用戶厭倦等待,轉投其它網站或APP。當你的用戶數量變得非常龐大,如何提高最大并發連接數,減少內存消耗也將變得非常重要。

在開發環境中,我們一般建議使用django-debug-toolbar和django-silk來進行性能監測分析。它們提供了每次用戶請求的響應時間,并告訴你程序執行過程哪個環節(比如SQL查詢)最消耗時間。

對于中大型網站或Web APP而言,最影響網站性能的就是數據庫查詢部分了。一是反復從數據庫讀寫數據很消耗時間和計算資源,二是當返回的查詢數據集queryset非常大時還會占據很多內存。我們先從這部分優化做起。

數據庫查詢優化利用Queryset的惰性和緩存,避免重復查詢

充分利用Django的QuerySet的惰性和自帶緩存特性,可以幫助我們減少數據庫查詢次數。比如下例中例1比例2要好。因為在你打印文章標題后,Django不僅執行了數據庫查詢,還把查詢到的article_list放在了緩存里,下次可以在其它地方復用,而例2就不行了。

# 例1: 利用了緩存特性 - Good article_list = Article.objects.filter(title__contains='django') for article in article_list: print(article.title) # 例2: Bad for article in Article.objects.filter(title__contains='django'): print(article.title)

但有時我們只希望了解查詢的結果是否存在或查詢結果的數量,這時可以使用exists()和count()方法,如下所示。這樣就不會浪費資源查詢一個用不到的數據集,還可以節省內存。

# 例3: Good article_list = Article.objects.filter(title__contains='django') if article_list.exists(): print('Records found.') else: print('No records') # 例4: Good count = Article.objects.filter(title__contains='django').count()一次查詢所有需要的關聯模型數據

假設我們有一個文章(Article)模型,其與類別(Category)是單對多的關系(ForeignKey), 與標簽(Tag)是多對多的關系(ManyToMany)。我們需要編寫一個article_list的函數視圖,以列表形式顯示文章清單及每篇文章的類別和標簽,你的模板文件可能如下所示:

{% for article in articles %} <li>{{ article.title }} </li> <li>{{ article.category.name }}</li> <li>{% for tag in article.tags.all %} {{ tag.name }},{% endfor %} </li> {% endfor %}

在模板里每進行一次for循環獲取關聯對象category和tag的信息,Django就要單獨進行一次數據庫查詢,造成了極大資源浪費。我們完全可以使用select_related方法和prefetch_related方法一次性從數據庫獲取單對多和多對多關聯模型數據,這樣在模板中遍歷時Django也不會執行數據庫查詢了。

# 僅獲取文章數據 - Bad def article_list(request): articles = Article.objects.all() return render(request, ’blog/article_list.html’,{’articles’: articles, }) # 一次性提取關聯模型數據 - Good def article_list(request): articles = Article.objects.all().select_related(’category’).prefecth_related(’tags’) return render(request, ’blog/article_list.html’, {’articles’: articles, })僅查詢需要用到的數據

默認情況下Django會從數據庫中提取所有字段,但是當數據表有很多列很多行的時候,告訴Django提取哪些特定的字段就非常有意義了。假如我們數據庫中有100萬篇文章,需要循環打印每篇文章的標題。如果按例4操作,我們會將每篇文章對象的全部信息都提取出來載入到內存中,不僅花費更多時間查詢,還會大量占用內存,而最后只用了title這一個字段,這是完全沒有必要的。我們完全可以使用values和value_list方法按需提取數據,比如只獲取文章的id和title,節省查詢時間和內存(例6-例8)。

# 例子5: Bad article_list = Article.objects.all() if article_list: print(article.title) # 例子6: Good - 字典格式數據 article_list = Article.objects.values(’id’, ’title’) if article_list: print(article.title) # 例子7: Good - 元組格式數據 article_list = Article.objects.values_list(’id’, ’title’) if article_list: print(article.title) # 例子8: Good - 列表格式數據 article_list = Article.objects.values_list(’id’, ’title’, flat=True) if article_list: print(article.title)

除此以外,Django項目還可以使用defer和only這兩個查詢方法來實現這一點。第一個用于指定哪些字段不要加載,第二個用于指定只加載哪些字段。

使用分頁,限制最大頁數

事實前面代碼可以進一步優化,比如使用分頁僅展示用戶所需要的數據,而不是一下子查詢所有數據。同時使用分頁時也最好控制最大頁數。比如當你的數據庫有100萬篇文章時,每頁即使展示100篇,也需要1萬頁展示給你的用戶,這是完全沒有必要的。你可以完全只展示前200頁的數據,如下所示:

LIMIT = 100 * 200 data = Articles.objects.all()[:(LIMIT + 1)] if len(data) > LIMIT: raise ExceededLimit(LIMIT) return data數據庫設置優化

如果你使用單個數據庫,你可以采用如下手段進行優化:

建立模型時能用CharField確定長度的字段盡量不用不用TextField, 可節省存儲空間; 可以給搜索頻率高的字段屬性,在定義模型時使用索引(db_index=True); 持久化數據庫連接。

沒有持久化連接,Django每個請求都會與數據庫創建一個連接,直到請求結束,關閉連接。如果數據庫不在本地,每次建立和關閉連接也需要花費一些時間。設置持久化連接時間,僅需要添加CONN_MAX_AGE參數到你的數據庫設置中,如下所示:

DATABASES = { ‘default’: { ‘ENGINE’: ‘django.db.backends.postgresql_psycopg2’, ‘NAME’: ‘postgres’, ‘CONN_MAX_AGE’: 60, # 60秒 } }

當然CONN_MAX_AGE也不宜設置過大,因為每個數據庫并發連接數有上限的(比如mysql默認的最大并發連接數是100個)。如果CONN_MAX_AGE設置過大,會導致mysql 數據庫連接數飆升很快達到上限。當并發請求數量很高時,CONN_MAX_AGE應該設低點,比如30s, 10s或5s。當并發請求數不高時,這個值可以設得長一點,比如60s或5分鐘。

當你的用戶非常多、數據量非常大時,你可以考慮讀寫分離、主從復制、分表分庫的多數據庫服務器架構。這種架構上的布局是對所有web開發語言適用的,并不僅僅局限于Django,這里不做進一步展開了。

緩存

緩存是一類可以更快的讀取數據的介質統稱,也指其它可以加快數據讀取的存儲方式。一般用來存儲臨時數據,常用介質的是讀取速度很快的內存。一般來說從數據庫多次把所需要的數據提取出來,要比從內存或者硬盤等一次讀出來付出的成本大很多。對于中大型網站而言,使用緩存減少對數據庫的訪問次數是提升網站性能的關鍵之一。

視圖緩存

from django.views.decorators.cache import cache_page @cache_page(60 * 15) def my_view(request): ...使用@cached_property裝飾器緩存計算屬性

對于不經常變動的計算屬性,可以使用@cached_property裝飾器緩存結果。

緩存臨時性數據比如sessions

Django的sessions默認是存在數據庫中的,這樣的話每一個請求Django都要使用sql查詢會話數據,然后獲得用戶對象的信息。對于臨時性的數據比如sessions和messages,最好將它們放到緩存里,也可以減少SQL查詢次數。

SESSION_ENGINE = ’django.contrib.sessions.backends.cache’

模版緩存

默認情況下Django每處理一個請求都會使用模版加載器都會去文件系統搜索模板,然后渲染這些模版。你可以通過使用cached.Loader開啟模板緩存加載。這時Django只會查找并且解析你的模版一次,可以大大提升模板渲染效率。

TEMPLATES = [{ ’BACKEND’: ’django.template.backends.django.DjangoTemplates’, ’DIRS’: [BASE_DIR / ’templates’], ’OPTIONS’: { ’loaders’: [ (’django.template.loaders.cached.Loader’, [ ’django.template.loaders.filesystem.Loader’, ’django.template.loaders.app_directories.Loader’, ’path.to.custom.Loader’, ]),], }, }]

注意:不建議在開發環境中(Debug=True)時開啟緩存加載,因為修改模板后你不能及時看到修改后的效果。

另外模板文件中建議使用with標簽緩存視圖傳來的數據,便于下一次時使用。對于公用的html片段,也建議使用緩存。

{% load cache %} {% cache 500 sidebar request.user.username %} .. sidebar for logged in user .. {% endcache %}靜態文件

壓縮 HTML、CSS 和 JavaScript等靜態文件可以節省帶寬和傳輸時間。Django 自帶的壓縮工具有GzipMiddleware 中間件和 spaceless 模板 Tag。使用Python壓縮靜態文件會影響性能,一個更好的方法是通過 Apache、Nginx 等服務器來對輸出內容進行壓縮。例如Nginx服務器支持gzip壓縮,同時可以通過expires選項設置靜態文件的緩存時間。

以上就是Django程序的優化技巧的詳細內容,更多關于Django程序的優化的資料請關注好吧啦網其它相關文章!

標簽: Django
相關文章:
主站蜘蛛池模板: 拼装地板,悬浮地板厂家,悬浮式拼装运动地板-石家庄博超地板科技有限公司 | 滑石粉,滑石粉厂家,超细滑石粉-莱州圣凯滑石有限公司 | 大行程影像测量仪-探针型影像测量仪-增强型影像测量仪|首丰百科 大通天成企业资质代办_承装修试电力设施许可证_增值电信业务经营许可证_无人机运营合格证_广播电视节目制作许可证 | 网络推广公司_网络营销方案策划_企业网络推广外包平台-上海澜推网络 | 冷却塔厂家_冷却塔维修_冷却塔改造_凉水塔配件填料公司- 广东康明节能空调有限公司 | 水厂自动化|污水处理中控系统|水利信息化|智慧水务|智慧农业-山东德艾自动化科技有限公司 | 筒瓦厂家-仿古瓦-寺庙-古建琉璃瓦-宜兴市古典园林建筑陶瓷厂有限公司 | 咖啡加盟,咖啡店加盟连锁品牌-卡小逗| led太阳能路灯厂家价格_风光互补庭院灯_农村市政工程路灯-中山华可路灯品牌 | 恒湿机_除湿加湿一体机_恒湿净化消毒一体机厂家-杭州英腾电器有限公司 | 台湾HIWIN上银直线模组|导轨滑块|TBI滚珠丝杆丝杠-深圳汉工 | 浴室柜-浴室镜厂家-YINAISI · 意大利设计师品牌 | 咿耐斯 |-浙江台州市丰源卫浴有限公司 | 低浓度恒温恒湿称量系统,强光光照培养箱-上海三腾仪器有限公司 | 天津试验仪器-电液伺服万能材料试验机,恒温恒湿标准养护箱,水泥恒应力压力试验机-天津鑫高伟业科技有限公司 | 真空冷冻干燥机_国产冻干机_冷冻干燥机_北京四环冻干 | 密集架|电动密集架|移动密集架|黑龙江档案密集架-大量现货厂家销售 | 自动气象站_农业气象站_超声波气象站_防爆气象站-山东万象环境科技有限公司 | 上海平衡机-单面卧式动平衡机-万向节动平衡机-圈带动平衡机厂家-上海申岢动平衡机制造有限公司 | 山东集装箱活动房|济南集装箱活动房-济南利森集装箱有限公司 | 招商帮-一站式网络营销服务|互联网整合营销|网络推广代运营|信息流推广|招商帮企业招商好帮手|搜索营销推广|短视视频营销推广 | 成都珞石机械 - 模温机、油温机、油加热器生产厂家 | 深圳成考网-深圳成人高考报名网| 西宁装修_西宁装修公司-西宁业之峰装饰-青海业之峰墅级装饰设计公司【官网】 | 卫生纸复卷机|抽纸机|卫生纸加工设备|做卫生纸机器|小型卫生纸加工需要什么设备|卫生纸机器设备多少钱一台|许昌恒源纸品机械有限公司 | 厂房出租-厂房规划-食品技术-厂房设计-厂房装修-建筑施工-设备供应-设备求购-龙爪豆食品行业平台 | 棕刚玉-白刚玉厂家价格_巩义市东翔净水材料厂 | 上海律师咨询_上海法律在线咨询免费_找对口律师上策法网-策法网 广东高华家具-公寓床|学生宿舍双层铁床厂家【质保十年】 | 报警器_家用防盗报警器_烟雾报警器_燃气报警器_防盗报警系统厂家-深圳市刻锐智能科技有限公司 | 陕西自考报名_陕西自学考试网 | 滑板场地施工_极限运动场地设计_滑板公园建造_盐城天人极限运动场地建设有限公司 | 手板-手板模型-手板厂-手板加工-生产厂家,[东莞创域模型] | 防潮防水通风密闭门源头实力厂家 - 北京酷思帝克门窗 | 手术室净化厂家_成都实验室装修公司_无尘车间施工单位_洁净室工程建设团队-四川华锐16年行业经验 | 北京发电车出租-发电机租赁公司-柴油发电机厂家 - 北京明旺盛安机电设备有限公司 | 粒米特测控技术(上海)有限公司-测功机_减速机测试台_电机测试台 | 苗木价格-苗木批发-沭阳苗木基地-沭阳花木-长之鸿园林苗木场 | 阿尔法-MDR2000无转子硫化仪-STM566 SATRA拉力试验机-青岛阿尔法仪器有限公司 | 合肥触摸一体机_触摸查询机厂家_合肥拼接屏-安徽迅博智能科技 | 对辊破碎机_四辊破碎机_双齿辊破碎机_华盛铭重工 | 防水套管厂家_刚性防水套管_柔性防水套管_不锈钢防水套管-郑州中泰管道 | 舞台木地板厂家_体育运动木地板_室内篮球馆木地板_实木运动地板厂家_欧氏篮球地板推荐 |