python比perl mySql查询慢5倍

时间:2014-11-06 15:55:35

标签: python mysql perl

我正在将代码从perl转换为python。 即使它的工作方式完全相同,但有一部分代码在python中比在perl中慢5倍,我无法弄清楚原因。

perl和python都在同一台机器上,以及mysql数据库。

代码查询数据库以下载表的所有列,然后处理每一行。 有超过500万行要处理,最大的问题是从数据库中检索数据到python处理。

这里我附上两个代码示例: 的Python:

import os
import mysql.connector **<--- import mySqlDb**
import time

outDict = dict()
## DB parameters
db = mysql.connector.connect **<----- mySqlDb.connect( ...** 
     (host=dbhost, 
user=username, # your username
passwd=passw, # your password
db=database) # name of the data base
cur = db.cursor(prepared=True)
sql = "select chr,pos,lengthofrepeat,copyNum,region from db.Table_simpleRepeat;"
cur.execute(sql)
print('\t eDiVa public omics start')
s  = time.time()
sz = 1000
rows = cur.fetchall()
for row in rows:
    ## process out dict    
print time.time() - s 
cur.close()
db.close()        

虽然这里有Perl等效脚本:

use strict;
use Digest::MD5 qw(md5);
use DBI;
use threads;
use threads::shared;

my $dbh = DBI->connect('dbi:mysql:'.$database.';host='.$dbhost.'',$username,$pass) 
    or die "Connection Error!!\n";    
    my $sql = "select chr,pos,lengthofrepeat,copyNum,region from   db.Table_simpleRepeat\;";
    ## prepare statement and query
    my $stmt = $dbh->prepare($sql);
    $stmt->execute or die "SQL Error!!\n";
    my $c = 0;
    #process query result
    while (my @res = $stmt->fetchrow_array) 
    {
        $edivaStr{ $res[0].";".$res[1] } = $res[4].",".$res[2]; 
        $c +=1;
    }
    print($c."\n");
    ## close DB connection
    $dbh->disconnect();    

这两个脚本的运行时是:

  • 〜40s用于Perl脚本
  • ~200s for Python script

我无法弄清楚为什么会发生这种情况[我尝试使用fetchone()或fetchmany()来查看是否存在内存问题,但运行时最多只能从200秒减少10%]。

我的主要问题是理解为什么两个功能等效的代码块之间存在相关的性能差异。

如何了解我如何验证发生的事情将不胜感激。

谢谢!

关于解决方案的更新

Peeyush&#39;评论可能是一个答案,我希望他发布它,因为它让我找到了解决方案。

问题是python连接器。我刚刚为mySqlDb模块更改了它,这是一个C编译模块。这使得python代码比perl代码略快。

我使用&lt; ----&#34;&#34;添加了python代码中的更改。表明获得表现是多么容易。

4 个答案:

答案 0 :(得分:4)

cursor.fetchall表示您一次将所有数据加载到内存中,而不是在需要时慢慢加载。

替换

row = cur.fetchall()
for row in rows:

通过

for row in cur:

答案 1 :(得分:2)

问题是python连接器。我刚刚为mySqlDb模块更改了它,这是一个C编译模块。这使得python代码比perl代码略快。

我在python代码中添加了一个&lt; ----“”来表示获得性能是多么容易

答案 2 :(得分:0)

如果其他人在使用 Python 和 MySQL 时遇到困难,我认为 Oracle 的 mysql.connector for Python 在执行 UPDATE 和 DELETE 时往往很慢。我发现 mysql.connector 执行 SELECT 查询的速度非常快,并且使用 .executemany() 执行 INSERT 的速度也非常快。但是,与我发现的相比,UPDATE 和 DELETE 非常缓慢。我决定采用的解决方案是将我的数据移至 PostgreSQL,因为我知道 Postgres 有一个非常好的 Python 库 (psycopg2)。无论如何,希望我的反馈有帮助!

答案 3 :(得分:-1)

Python for循环非常慢。您应该研究一种替代方法来处理您的查询 来自python wiki:https://wiki.python.org/moin/PythonSpeed/PerformanceTips#Loops