我写了一个 Python 脚本来将一些数据(3 亿)插入到 MySQL 表中:
#!/usr/bin/python
import os
import MySQLdb
from multiprocessing import Pool
class DB(object):
def __init__(self):
self.conn = MySQLdb.connect(host='localhost',user='root',passwd='xxx',db='xdd',port=3306)
self.cur = self.conn.cursor()
def insert(self, arr):
self.cur.execute('insert into RAW_DATA values(null,%s,%s,%s,%s,%s,%s,%s)', arr)
def close(self):
self.conn.commit()
self.cur.close()
self.conn.close()
def Import(fname):
db = DB()
print 'importing ', fname
with open('data/'+fname, 'r') as f:
for line in f:
arr = line.split()
db.insert(arr)
db.close()
if __name__ == '__main__':
# 800+ files
files = [d for d in os.listdir('data') if d[-3:]=='txt']
pool = Pool(processes = 10)
pool.map(Import, files)
问题是,脚本运行非常非常慢,multiprocessing 有没有明显的错误使用?
最佳答案
是的,如果您要将 3 亿行批量插入到同一个表中,那么您不应该尝试将此插入并行化。所有的insert都要经过同样的瓶颈:更新索引,写入硬盘上的物理文件。这些操作需要对底层资源(索引或磁盘头)进行独占访问。
您实际上是在数据库上增加了一些无用的开销,现在必须处理多个并发事务。这会消耗内存,强制上下文切换,使磁盘读头一直跳来跳去,等等。
将所有内容插入同一个线程。
看起来您实际上是从一种 CSV 文件中导入数据。您可能想使用内置的 LOAD DATA INFILE
MySQL 命令,专为此目的而设计。如果您在调整此命令时需要一些帮助,请描述您的源文件。
关于 python : What's wrong with my code of multi processes inserting to MySQL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17816477/