2013-01-08 74 views
3

我已经在我的应用程序中向mysql的​​函数发出缓慢的声音。我制作了一个简单的sql查询来解释这个问题:python mysql execute()很慢

SELECT * FROM `cid444_agg_big` c WHERE 1 

>>> import MySQLdb as mdb 
>>> import time; 
>>> 
>>> dbconn = mdb.connect('localhost','*****','*****','*****'); 
>>> cursorconn = dbconn.cursor() 
>>> 
>>> sql="SELECT * FROM `cid444_agg_big` c WHERE 1"; 
>>> 
>>> startstart=time.time(); 
>>> cursorconn.execute(sql); 
21600L #returned 21600 records 
>>> print time.time()-startstart, "for execute()" 
2.86254501343 for execute() #why does this take so long? 
>>> 
>>> startstart=time.time(); 
>>> rows = cursorconn.fetchall() 
>>> print time.time()-startstart, "for fetchall()" 
0.0021288394928 for fetchall() #this is very fast, no problem with fetchall() 

在mysql shell中运行此查询会产生0.27秒或10倍的更快!

我唯一的想法就是返回数据的大小。这将返回21600“宽”行。所以这是很多数据被发送到Python。数据库是localhost,所以没有网络延迟。

为什么这需要这么长时间?

更新的详细信息

我写在PHP一个类似的脚本:

$c = mysql_connect ('localhost', '*****', '****', true); 
mysql_select_db ('cachedata', $c); 

$time_start = microtime_float(); 
$sql="SELECT * FROM `cid444_agg_big` c WHERE 1"; 
$q=mysql_query($sql);$c=0; 
while($r=mysql_fetch_array($q)) 
$c++;//do something? 
echo "Did ".$c." loops in ".(microtime_float() - $time_start)." seconds\n"; 


function microtime_float(){//function taken from php.net 
    list($usec, $sec) = explode(" ", microtime()); 
    return ((float)$usec + (float)$sec); 
} 

此打印:

Did 21600 loops in 0.56120800971985 seconds 

这个循环上的所有数据,而不是在获取所有的一旦。 PHP似乎比Python版本快6倍 ....

回答

2

The default MySQLdb cursor获取完整的结果集在客户端上execute,并且fetchall()将不仅仅是数据从内存中拷贝到内存中。

如果要将结果集存储在服务器上并按需获取,则应该使用SSCursor来代替。

Cursor:
这 是标准类光标返回行作为元组并将结果保存在客户端设置。

SSCursor:
这是一个Cursor类返回行的元组,并将结果存储在服务器中设定。

+0

我正在循环使用所有这些数据。我是否正确地认为在我的情况下运行'execute()'并获取所有内容大致等价于使用'SSCursor'的方法,并假设我需要所有这些记录并根据需要提取记录? 'SSCursor'会在时间上获得实质性收益吗? – Landon

+0

@Landon如果你正在提取所有数据,我会假设'Cursor'更快,因为它可以传输所有数据而不考虑任何访问模式。 'SSCursor'主要适用于不一定使用所有数据的查询,或者用于大型结果集来节省内存。 –

+0

值得注意的是,使用SSCursor,你不能打开一个到数据库的新连接,或者直到关闭当前的游标才执行一个新的查询。 –