为了账号安全,请及时绑定邮箱和手机立即绑定

话说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 关注
  • 1058 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信