2009年 9月27日晚上快下班時分,有羣裏面的朋友說python的MySQLdb在檢索百萬數據量的時候巨慢無比,要達到20分鐘左右。由於自己的一些項目也用到了MySQLdb,所以特別注意了一下,於是翻閱了源代碼。而後經過大半天對其源碼的分析,初步得出一些結論。
MySQLdb的性能影響主要是由於_mysql.c代碼頁中的self->use以及個別函數中的use參數=1或者0時引起的。由於在函數_mysql_ResultObject_Initialize中,利用:
Py_BEGIN_ALLOW_THREADS;
if (use)
result = mysql_use_result(&(conn->connection));
else
result = mysql_store_result(&(conn->connection));
由這段來決定是採用mysql_use_result還是mysql_store_result。衆所周知mysql_use_result連MySQL官方都不大推薦。建議上述代碼中將if (use)改爲if(self->use==1),此外建議將函數_mysql_ConnectionObject_store_result中的:
改爲:
另外將_mysql_ConnectionObject_use_result函數中的:
改爲:
總之說了這麼多,關鍵是儘可能使用mysql_store_result。
爲了便於大家對MySQLdb的理解,我把修改成功的代碼附上。我用的是1.2.3的測試版,爲了不和你已經安裝的MySQLdb衝突,我把相關代碼都改成了mysqldb2,模塊名稱都是_mysql2.so。打開代碼後,make一下會自動生成_mysql2.so。然後執行外面一個測試的代碼:
尤其在數據超過200w後,可能會發現這個效果。原先需要20分鐘,現在大概幾十秒。修改後的源碼我放在QQ羣共享裏面。
不知道現在還在不在
QQ羣:24683344 ,裏面有一些牛人。從事方向各不相同。