Webフォームを介してデータベースにCSVファイルをロードしています。なぜ私のテーブルにデータを入力するのに時間がかかりますか?
生データの順序は各CSVファイルで一貫していますが、ソースごとにファイルごとに変更されるため、5行を表示するプレビューフォームがあり、ドロップで列を割り当てることができます表の有効な列名のリスト。
次に、cgiフォームを使用してINSERT文を作成し、csvファイルを行単位で解析して表に移入します。
しかし、それは非常に遅いです。私は同時に、961402行(値を持つ7つの列)と1835538行(値を持つ1つの列)を持つ2つの表を同時に投入しており、それぞれ少なくとも30分実行しています。私は毎秒100の新しい行のような何かを見ているだけです。
ここで私が遅くなるものは見えますか?
注:私はここにいくつかの醜いコードがあることを知っています、それは私がこの言語を理解しながら書いた最初のpython CGIスクリプトの一つでした。
for item in form:
field = form.getvalue(item)
field = cgi.escape(field)
if field == 'null':
pass
elif item == 'csvfile':
pass
elif item == 'campaign':
pass
elif item == 'numfields':
pass
else:
colname = str(colname) + ", " + str(item)
colnum.append(field)
assert(numfields > 0)
placeholders = (numfields-1) * "%s, " + "%s"
query = ("insert into %s (%s)" % (table, colname.lstrip(",")))
with open(fname, 'rb') as f:
reader = csv.reader(f)
try:
record = 0
errors = 0
for row in reader:
try:
record = record + 1
data = ''
for value in colnum:
col = int(value)
rawrow = row[col]
saferow = rawrow.replace("'", "-")
saferow = saferow.replace("-", "")
data = str(data) + ", '" + saferow + "'"
dataset = data.lstrip(',')
insert = query + (" values (%s)" % dataset)
cur.execute(insert)
con.commit()
print ".",
except IndexError, e:
print "Row:%d file %s, %s<br>" % (reader.line_num, fname.lstrip("./files/"), e)
errors = errors + 1
except csv.Error, e:
print "Row:%s file %s, line %d: %s<br>" % (record, fname, reader.line_num, e)
errors = errors + 1
except mdb.Error, e:
print "Row:%s Error %d: %s<br>" % (record, e.args[0], e.args[1])
errors = errors + 1
except:
t,v,tb = sys.exc_info()
print "Row:%s %s<br>" % (record, v)
errors = errors + 1
except csv.Error, e:
print "except executed<br>"
sys.exit('file %s, line %d: %s' % (fname, reader.line_num, e))
print "Succesfully loaded %s into Campaign %s, <br>" % (fname.lstrip("./files/"), table)
print record - errors, "new records.<br>"
print errors, "errors.<br>"
EDIT/UPDATE:LOAD DATA LOCAL INFILE
を使用するには、魔法のように働いていた、私は分未満で600Kレコードをロード。
新しいコードもクリーナーです。
else:
colnum.append([field, item])
sortlist = sorted(colnum, key=itemgetter(0))
cols = ''
for colname in sortlist:
cols = cols + "%s, " % colname[1]
cur.execute("LOAD DATA LOCAL INFILE '%s' IGNORE INTO TABLE %s FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' (%s)" % (fname, table, cols.rstrip(', ')))
con.commit()
唯一の難点は、そうでない場合は、魔法のように動作し、私はデータの整合性を確保するために、私のCSVファイルを準備するsmidgeより多くの仕事をしなければならないということです。
行番号を削除してください - 作業が難しくなります。 –
大きなテーブルにINSERT INTO sqlクエリを実行するとかなり遅くなることがあります。 INSERT INTOでいっぱいになったファイルを作成し、手動でSQLクライアントを実行して、私の意図を確認してください。 – Paul
それは私が思っていることです、@ポール、しかしこれは遅いですか? 2つの間に200レコードがクロールしているようです。それをスピードアップする方法はありますか?列はすべてCHARデータ型です。 – TaoJoannes