记项目 Python-MySQL 访问类的优化

标签: 项目 python mysql | 发表时间:2011-07-29 23:20 | 作者:(author unknown) litefy
出处:http://simple-is-better.com/

背景

接手一些Python项目的后续开发与维护,发现这些项目都用同一个数据库访问类,而生成的结果行竟然是用list存的,一个简单的row['id']访问需要遍历整行去找,遂优化之

改写成dict

一般访问数据行的字段都是使用字段名访问,显然应该使用dict。但也有可能使用数字下标访问,例如对于select count(*)的结果集,可能就使用rs[0][0]访问了。因此还需要一个list去存结果集的字段名顺序。

其实MySQLdb Driver有DictCursor可直接获得dict结果。当结果集的列有重复字段,第二个重名字段会加上表别名前缀。例如select * FROM tableA as A, tableB as B,两个表都有字段id,tableB的id会使用B.id这个key。
对于可以用下标访问的需求,也需要额外加个list来存字段名顺序。这个list是从cursor的description生成的。问题在于cursor的description里,tableB的id的字段名仍然是id,当想用下标访问tableB的id时,查找list获得id这个字段名,得到的却是tableA的结果。暂时没有想到解决这个问题的方法。因此还是使用默认cursor,手动生成结果集。

结果测试

改写成dict后,测试耗时只有原来的50%。对于列很多的结果集,从原来遍历整行O(n)才拿到结果,变成O(1),改善还是很客观的。

使用Cython进一步加速

在纯Python的基础上,已经很难再有提高了。考虑使用Cython将其编译成C extension。对于数据库访问类这种“底层”的类,平时很少会改动,但使用非常频繁,进一步优化还是值得的。

对于能确定静态类型的地方,例如for循环中的i,自定义的Python class,都用cdef指定类型。对于参数或者返回值中有能确定静态类型的Python函数,也可以使用cpdef修饰。

编译后测试,耗时只有改成dict后版本的1/7左右,是原始未优化版本的6%左右,速度提升有15倍!

项目实测

以上的测试结果只是纯跑分的测试,实际效果还是要放到本来的项目体现。找了一个报表的调用,数据库查询结果是5k行。

$ time -p curl -s http://app08.gz/fd/data/pilfered_time_txt/?btime=2011-07-04\&etime=2011-07-11\&product=mh\&get_state= | wc -l
5737
real 4.48
user 0.01
sys 0.22
$ time -p curl -s http://localhost:8004/fd/data/pilfered_time_txt/?btime=2011-07-04\&etime=2011-07-11\&product=mh\&get_state= | wc -l
5737
real 2.42
user 0.02
sys 0.13

上面的是未优化版本的结果
下面的是使用c extension版本的结果,大约有45%的提升。

PS:
在import cython生成的so时,曾经遇到ImportError

>>> import db
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initdb)

解决方法是注意生成cython扩展的setup.py,ext_modules里面的Extension的第一个参数必须是你将来要import的名字。例如我要import db,那么就要写成:

ext_modules = [Extension("db", ["db.pyx"])]

对于生成的so,可以使用

strings db.so | grep db

来查看是否正确生成了initdb这个入口。

# 来源:不沉之月


在微博上关注: 新浪, 腾讯   投稿

最新招聘

更多>>

相关 [项目 python mysql] 推荐:

记项目 Python-MySQL 访问类的优化

- litefy - python.cn(jobs, news)
接手一些Python项目的后续开发与维护,发现这些项目都用同一个数据库访问类,而生成的结果行竟然是用list存的,一个简单的row['id']访问需要遍历整行去找,遂优化之. 一般访问数据行的字段都是使用字段名访问,显然应该使用dict. 但也有可能使用数字下标访问,例如对于select count(*)的结果集,可能就使用rs[0][0]访问了.

2013流行Python项目汇总

- - ITeye资讯频道
Python作为程序员的宠儿,越来越得到人们的关注,使用Python进行应用程序开发的越来也多. 那么,在2013年有哪些流行的Python项目呢. python_koans:Python Koans 算 “Ruby Koans” 的一部分,作为交互式教程,可以学习. sure:Sure 是最适合自动化测试的 Python 工具,包含流利的断言、深度选择器等等特性.

值得学习的python项目

- - CSDN博客编程语言推荐文章
此网站整理的2014年值得一学的pytho项目,http://pycoders.com/2014/. 项目资源都在github上,python程序员进阶必备. Nice looking web dashboard written in Flask that can display data about your system and its processes as returned by psutil.

快速熟悉python 下使用mysql(MySQLdb) - mrbean

- - 博客园_首页
首先你需要安装上mysql和MySQLdb模块(当然还有其他模块可以用),这里我就略过了,如果遇到问题自行百度(或者评论在下面我可以帮忙看看). 这里简单记录一下自己使用的学习过程:.   MySQLdb提供了connect函数,使用如下.    这里的参数的意义都是很明确的,但是这些参数并不是都是必须的:.

使用VitrualEnvWrapper隔离python项目的库依赖

- jeff - Jeff的妙想奇境
VirtualEnv用于在一台机器上创建多个独立的python运行环境,VirtualEnvWrapper为前者提供了一些便利的命令行上的封装. - 隔离项目之间的第三方包依赖,如A项目依赖django1.2.5,B项目依赖django1.3. - 为部署应用提供方便,把开发环境的虚拟环境打包到生产环境即可,不需要在服务器上再折腾一翻.

Python项目自动化部署最佳实践@搜狐

- - the5fire的技术博客
今天主要介绍下我们组刚刚开源出来的一个自动化部署的工具 essay ,功能在readme上已经介绍的很详细了,这篇文章只是介绍下外围的情况,产生的环境,一些决策的考虑. 事情还得从头开始说起,从那些自动化的fabric文件开始,也从我刚入职搜狐负责手机搜狐开发开始说起. 我参与开发的时候项目的部署已经是自动化了,不过并没有抽象出一个工具来.

2013年最好的Python开源项目汇总

- - ITeye资讯频道
2013年Python社区诞生了很多实用的开发工具,这些工具在一定程度上可以帮助你节省更多的时间. 本文为你汇总了这些工具,它们大部分都是开源的,你还可以通过源码来学习更多的Python开发知识. Radon是一个用于从源代码中计算出各种指标的Python工具,包括:. McCabe复杂性计算,也就是循环复杂度.

Python 项目推介:扇贝网,一个从 2 到 30 万的故事

- 杀手 - python.cn(jobs, news)
我想说一说“扇贝网 http://shanbay.com”,一家致力于帮助英语学习者解决词汇问题的网站,我是创始人之一. 在创办扇贝网之前,我曾经花了几个月时间看完一本原版的达芬奇密码,期间最为纠结的无非是随处可见的英语生词,一开始我还能不厌其烦的查字典做记录,但是发现这些生词再次出现,我依然不记得是什么意思;屡经挫折后,我渴望能有一个网站让我在看书或者文章过程中把遇到的单词丢进去,而后我只要登录这一网站,它就能按照一定规律提醒我复习.

疑Google员工把8w行Python项目用4w行Java重写了

- - est's blog
发信人: daluobu (阿土仔), 信区: Python. 标 题: 终于把一个8万行的Python程序用Java重写了. 发信站: 水木社区 (Fri Dec 6 08:10:26 2013), 转信. 在噩梦般地维护了一年多一个8万多行的Python程序之后,终于争取到机会把这个破烂玩.

项目进阶 之 集群环境搭建(二)MySQL集群

- - CSDN博客推荐文章
        上次的博文中我们介绍了一下集群的相关概念,今天的博文我们介绍一下MySQL集群的相关内容.         MySQL群集技术在分布式系统中为MySQL数据提供了冗余特性,增强了安全性,使得单个MySQL服务器故障不会对系统产生巨大的负面效应,系统的稳定性得到保障.         MySQL群集需要有一组计算机,每台计算机的角色可能是不一样的.