遇到了Django中的慢查询

183 views
Skip to first unread message

Alvin Qi

unread,
Nov 15, 2017, 10:59:16 PM11/15/17
to python-cn(华蟒用户组,CPyUG 邮件列表)
作为一名Python & Django 新人,刚上手就遇到这样奇怪的问题。

需要查询的库:这里做了一个横向分表的操作,将一个很大的表手动水平分为若干结构相同的小表,每个小表中存有几十万到一百万不等的数据。

查询场景:需要从这一组表中查询一批数据,查询格式是SELECT WHERE IN这种,输入的参数条件相同,每个小表挨个查。

Django中的查询:
1)先是按照以上思路写出ORM形式的查询,发现整个过程非常慢,单表约1~3s,总共需要30s左右;
2)之后又写成raw sql形式的查询,通过 cursor.execute('...')这样的形式区执行,发现没有太大改变,依旧需要30s左右的查询时间。

SQL中的查询:
在开发过程中发现,如果把那些raw sql放在DB中直接查询,每个表需要不到1s,总共查询时间不超过5s。

问题:
1)为什么会出现这样的情况?
2)针对这个场景,除了业务级缓存之外,还有哪些优化的方法?

YS.Zou

unread,
Nov 16, 2017, 12:35:11 AM11/16/17
to pyth...@googlegroups.com
> 1)为什么会出现这样的情况?

可能点:

1. 每次查询都要创建连接。
2. 多次查询是串行的。


> 2)针对这个场景,除了业务级缓存之外,还有哪些优化的方法?

1. 换个不需要手动分表的,功能更强大的数据库产品。
2. 考虑一下分表的那个键是否合理,每次查询需要“每个小表挨个查”,这个不知道是一个什么场景啦,一般只需要查询确定的那些小表才对。
3. 如果是单纯的,偏查询,少更改或无更改的业务场景,可以考虑专门的“联机分析”趋向的方案。


--
邮件来自: `CPyUG`华蟒用户组(中文Python技术邮件列表)
规则: http://code.google.com/p/cpyug/wiki/PythonCn
详情: http://code.google.com/p/cpyug/wiki/CpyUg
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
---
您收到此邮件是因为您订阅了Google网上论坛上的“python-cn(华蟒用户组,CPyUG 邮件列表)”群组。
要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到python-cn+unsubscribe@googlegroups.com
要发帖到此群组,请发送电子邮件至python-cn@googlegroups.com
要查看更多选项,请访问https://groups.google.com/d/optout



--
进出自由才是游戏者的生存之道。

http://www.zouyesheng.com

金浩

unread,
Nov 16, 2017, 1:03:14 AM11/16/17
to pyth...@googlegroups.com, pyth...@googlegroups.com
每个小表才100万,直接别分表不行吗?


发自网易邮箱大师
要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到python-cn+...@googlegroups.com
要发帖到此群组,请发送电子邮件至pyth...@googlegroups.com
要查看更多选项,请访问https://groups.google.com/d/optout

Alvin Qi

unread,
Nov 16, 2017, 1:12:24 AM11/16/17
to python-cn(华蟒用户组,CPyUG 邮件列表)


在 2017年11月16日星期四 UTC+8下午1:35:11,YS.Zou写道:
> 1)为什么会出现这样的情况?

可能点:

1. 每次查询都要创建连接。
第一点确定不需要,这个我做过手动处理。 
2. 多次查询是串行的。
没错,多次查询是串行的,但单就每次查询情况而言,在Django中执行也要比在SQL中执行耗时多好多。 


> 2)针对这个场景,除了业务级缓存之外,还有哪些优化的方法?

1. 换个不需要手动分表的,功能更强大的数据库产品。
目前用的MySQL 
2. 考虑一下分表的那个键是否合理,每次查询需要“每个小表挨个查”,这个不知道是一个什么场景啦,一般只需要查询确定的那些小表才对。
这个可能是我没有描述清楚。这个场景里总共分了16个表,每次做查询用到的表是这16个表的子集,也就是说会用到若干个表,挨个查。 
3. 如果是单纯的,偏查询,少更改或无更改的业务场景,可以考虑专门的“联机分析”趋向的方案。
OLAP我明白,但这里并非偏查询,还涉及其他一些操作,总之场景不合适。 

感谢回复。 

Alvin Qi

unread,
Nov 16, 2017, 1:14:24 AM11/16/17
to python-cn(华蟒用户组,CPyUG 邮件列表)
行不行我说了不算,这是我刚接手的的一个老项目,它现在就是这样的。
如果是我一开始设计,我不会采取这样的方案,今后重构我也不打算用现在这套设计;现在就是左右为难,想解决。

在 2017年11月16日星期四 UTC+8下午2:03:14,金浩写道:

vicalloy

unread,
Nov 16, 2017, 1:26:03 AM11/16/17
to pyth...@googlegroups.com
找工具调试一下,看具体是哪里出的问题。

Alvin Qi

unread,
Nov 16, 2017, 2:05:04 AM11/16/17
to python-cn(华蟒用户组,CPyUG 邮件列表)
这个工具真不错!感谢推荐!

在 2017年11月16日星期四 UTC+8下午2:26:03,vicalloy写道:

piglei

unread,
Nov 16, 2017, 5:07:22 AM11/16/17
to pyth...@googlegroups.com
结果集大不大?会访问结果集吗?有时候访问大结果集也很耗时。

Alvin Qi

unread,
Nov 16, 2017, 8:07:22 AM11/16/17
to python-cn(华蟒用户组,CPyUG 邮件列表)
结果集不大,实际上相对于库里的数据来说,非常小了,根据使用的情况看,不会超过100条。

在 2017年11月16日星期四 UTC+8下午6:07:22,猪之哀伤写道:

Shell Xu

unread,
Nov 20, 2017, 9:25:03 PM11/20/17
to CUPG
你的问题其实就一句,怎么对python的sql查询做profiling呗。
你试试先抓包,看看rawsql的请求-回应网络周期是不是短的那种。如果网络周期很短,说明本地计算周期很长。如果网络周期很长,说明请求包构造本身就不一样了。估计是什么参数设定导致服务器端耗时增加。如果是mysql的话,是有工具可以解开报文的。

--
邮件来自: `CPyUG`华蟒用户组(中文Python技术邮件列表)
规则: http://code.google.com/p/cpyug/wiki/PythonCn
详情: http://code.google.com/p/cpyug/wiki/CpyUg
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
---
您收到此邮件是因为您订阅了Google网上论坛上的“python-cn(华蟒用户组,CPyUG 邮件列表)”群组。
要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到python-cn+unsubscribe@googlegroups.com
要发帖到此群组,请发送电子邮件至python-cn@googlegroups.com
要查看更多选项,请访问https://groups.google.com/d/optout



--
彼節者有間,而刀刃者無厚;以無厚入有間,恢恢乎其於游刃必有餘地矣。
blog: http://shell909090.org/

Alvin Qi

unread,
Nov 21, 2017, 1:34:52 AM11/21/17
to pyth...@googlegroups.com
感谢提供思路,我会顺着这个思路追一下。

您收到此邮件是因为您订阅了Google网上论坛上“python-cn(华蟒用户组,CPyUG 邮件列表)”群组中的主题。
要退订此主题,请访问https://groups.google.com/d/topic/python-cn/MdlXUMCnRUo/unsubscribe
要退订此群组及其所有主题,请发送电子邮件到python-cn+unsubscribe@googlegroups.com

要发帖到此群组,请发送电子邮件至python-cn@googlegroups.com
要查看更多选项,请访问https://groups.google.com/d/optout



--
Alvin Qi
Reply all
Reply to author
Forward
0 new messages