4

我在我的应用程序中发现execute()了 mysql 功能的缓慢。我制作了一个简单的 sql 查询来说明这个问题:

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。数据库是本地主机,因此没有网络延迟。

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

更新更多信息

我在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 倍....

4

2 回答 2

2

默认的 MySQLdb 游标将完整的结果集获取到客户端execute,并且fetchall()只会将数据从内存复制到内存。

如果要将结果集存储在服务器上并按需获取,则应改用SSCursor

Cursor:
这是标准的 Cursor 类,它将行作为元组返回并将结果集存储在客户端中。

SSCursor:
这是一个 Cursor 类,它以元组的形式返回行并将结果集存储在服务器中。

于 2013-01-08T22:10:56.493 回答
0

非常古老的讨论,但我尝试添加我的 2 美分。脚本必须按时间戳在多行中进行选择。在标准情况下(id 索引、名称、时间戳)非常慢(我没有检查但几分钟,很多分钟)。我也为时间戳添加了一个索引。查询时间不到 10 秒。好多了。

"ALTER TABLE BTC ADD INDEX(timestamp)"

我希望能提供帮助。

于 2021-09-09T20:37:10.623 回答