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シェルで実行すると、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 カーソルは、完全な結果セットをクライアントにフェッチしexecutefetchall()データをメモリからメモリにコピーするだけです。

結果セットをサーバーに保存し、オンデマンドでフェッチする場合は、代わりにSSCursorを使用する必要があります。

Cursor:
これは、行をタプルとして返し、結果セットをクライアントに格納する標準の Cursor クラスです。

SSCursor:
行をタプルとして返し、結果セットをサーバーに格納する Cursor クラスです。

于 2013-01-08T22:10:56.493 に答える