亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

話說Django orm模型為什么比原生的mysqldb慢

話說Django orm模型為什么比原生的mysqldb慢

呼如林 2019-05-14 09:08:10
話說Django orm模型為什么比原生的mysqldb慢
查看完整描述

2 回答

?
交互式愛情

TA貢獻1712條經驗 獲得超3個贊

首先確認下mysql索引問題.

進入mysql,查看索引情況 , 命中索引.

mysql> explain SELECT sum(idate_count) FROM buzz_keyword_historyWHERE ( buzz_keyword_history . date < ’2015-09-20 00:00:00′ ANDbuzz_keyword_history . date >= ’2015-09-01 00:00:00′ ANDbuzz_keyword_history . value = ‘手機’);

+—-+————-+———————-+——+——————————–+———-+———+——-+——+————————————+

| id | select_type | table                | type | possible_keys                  | key      | key_len | ref   | rows | Extra                              |

+—-+————-+———————-+——+——————————–+———-+———+——-+——+————————————+

|  1 | SIMPLE      | buzz_keyword_history | ref  | in_value,in_idate,search_speed | in_value | 182     | const | 1514 | Using index condition; Using where |

+—-+————-+———————-+——+——————————–+———-+———+——-+——+————————————+

1 row in set (0.00 sec)

然后在看了下mysql服務器的負載情況,load特別的底下.

Python

avg-cpu:  %user   %nice %system %iowait  %steal   %idle           2.80    0.00    1.22    0.41    0.00   95.57Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %utilsdc               0.00   808.61   21.65   27.02  5531.93  6685.05   251.00     0.55   11.39   0.71   3.45sdb               0.00   126.81    3.30    4.95   823.13  1054.05   227.75     0.37   44.44   1.50   1.24sda               0.06   215.50    2.46    7.87   599.12  1786.94   231.10     0.81   78.76   1.37   1.41memdiska          0.00     0.00  585.63 2638.44 84515.95 21107.53    32.76     0.15    0.05   0.03   8.54dm-0              0.00     0.00    0.00    0.00     0.00     0.00     8.00     0.00    4.39   1.13   0.00

接著在mysql server開啟了慢查詢sql語句調試模式,發現slow.log沒有特別的日志…都是跟本業務無關的慢查詢.

整個頁面的靜態文件也是加載正常,速度也是給力,雖然在nginx里沒有配置強制緩存… 但為毛數據加載這么慢 ,為毛 ?


最后不得不重新懷疑mysql查詢,我們開始統計整個django orm語句消耗的時間,一看非常的驚人,居然消耗了6秒的時間… 原本以為django 的orm只是幫助我們做了sql語句的映射,說實話我以前還真的就這么想。

Python

run_func.objects.filter(date__gte=d[0], date__lt=d[1],value=value).aggregate(Sum(idate_or_cdate + '_count'))

又看了django orm model的介紹,這django模型不簡單呀,他的返回值是querysets類型。 也就是說,他會把orm執行的結果,轉換成queryset結構 。 就因為這樣被封裝,所以我們每次用orm感覺特別友好的原因。

解決的方法,直接走原生的mysql sql語句,在python下你的選擇 mysqldb,也可以用django的connection。推薦用connection,因為大家的db地址配置都是放在settings.config里面的。

下面是django 運行原始sql語句的方法,大家參考下..

Python

from django.db import connection, transactionimport MySQLdb.......cursor = connection.cursor(cursorclass = MySQLdb.cursors.DictCursor)cursor.execute(sql,None)如果你有多個數據庫,可以在connections選擇數據庫。from django.db import connectionscursor = connections['xiaorui'].cursor()transaction.commit_unless_managed(using='xiaorui')

最終的結果,使用原生的sql語句用了不到1秒,而用django的orm是6秒左右..   快了好幾倍… 

我覺得django orm應該多加個是否要轉換成queryset的參數,這樣我們根據需求來進行配置。  下面是我用django debug的結果.. 可以看到速度提升了不少.






查看完整回答
反對 回復 2019-05-15
?
元芳怎么了

TA貢獻1798條經驗 獲得超7個贊

首先確認下mysql索引問題.
進入mysql,查看索引情況 , 命中索引.
mysql> explain
SELECT sum(idate_count) FROM buzz_keyword_historyWHERE
( buzz_keyword_history . date < ’2015-09-20 00:00:00′
ANDbuzz_keyword_history . date >= ’2015-09-01 00:00:00′
ANDbuzz_keyword_history . value = ‘手機’);
+—-+————-+———————-+——+——————————–+———-+———+——-+——+————————————+
|
id | select_type | table | type | possible_keys
| key | key_len | ref | rows | Extra
|
+—-+————-+———————-+——+——————————–+———-+———+——-+——+————————————+
|
1 | SIMPLE | buzz_keyword_history | ref |
in_value,in_idate,search_speed | in_value | 182 | const | 1514 |
Using index condition; Using where |
+—-+————-+———————-+——+——————————–+———-+———+——-+——+————————————+
1 row in set (0.00 sec)




查看完整回答
反對 回復 2019-05-15
  • 2 回答
  • 0 關注
  • 1093 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號