2

Python スクリプトによって生成されたデータを MySQL データベースに保存しようとしています。基本的に私はコマンドを使用しています:

con = oursql.connect(user="user", host="host", passwd="passwd", 
                     db="testdb")
c = con.cursor()                             

c.executemany(insertsimoutput, zippedsimoutput)

con.commit()
c.close()

どこ、

insertsimoutput = '''insert into simoutput 
                        (repnum, 
                         timepd, 
                         ...) values (?, ?, ...?)'''

約 30,000 行が挿入され、約 15 列あります。上記は約7分かかります。oursql の代わりに MySQLdb を使用すると、約 2 秒かかります。なぜこの大きな違いが?これは、oursql で別の方法で実行する必要がありますか? oursql は単純に遅いのでしょうか? このデータを oursql で挿入するより良い方法があれば、教えていただければ幸いです。

ありがとうございました。

4

3 に答える 3

7

違いは、MySQLdb はクエリに対して何らかのハッキングを行いますが、oursql はそうではありません...

これを取る:

cursor.executemany("INSERT INTO sometable VALUES (%s, %s, %s)",
    [[1,2,3],[4,5,6],[7,8,9]])

MySQLdb は、これを実行する前にこれを変換します。

cursor.execute("INSERT INTO sometable VALUES (1,2,3),(4,5,6),(7,8,9)")

しかし、そうする場合:

cursor.executemany("INSERT INTO sometable VALUES (?, ?, ?)",
    [[1,2,3],[4,5,6],[7,8,9]])

oursql では、次の擬似コードのようなものに変換されます。

stmt = prepare("INSERT INTO sometable VALUES (?, ?, ?)")
for params in [[1,2,3],[4,5,6],[7,8,9]]:
    stmt.execute(*params)

したがって、mysqldb が行っていることをエミュレートしたいが、プリペアド ステートメントや oursql のその他の利点を活用したい場合は、次のようにする必要があります。

from itertools import chain
data = [[1,2,3],[4,5,6],[7,8,9]]
one_val = "({})".format(','.join("?" for i in data[0]))
vals_clause = ','.join(one_val for i in data)
cursor.execute("INSERT INTO sometable VALUES {}".format(vals_clause),
    chain.from_iterable(data))

これを行うと、SQLが高速になるに違いありません:-)

また、あなたがそれを醜いと思うなら、あなたは正しいです。しかし、MySQL db は内部的に醜いことをしていることを覚えておいてください - 正規表現を使用して INSERT ステートメントを解析し、パラメータ化された部分を分割し、私が oursql に対して行うことを提案したことを実行します。

于 2014-06-19T22:07:39.293 に答える
1

パフォーマンスを向上させるためoursqlのSQLコマンドをサポートしているかどうかを確認するといいでしょう。bulk insert

于 2012-06-16T05:50:32.100 に答える
0

Oursql はbulk insertステートメントをサポートしています。sqlalchemy ラッパーを使用して、そのためのコードを作成しました。

純粋な oursql の場合、次のようなもので問題ありません。

with open('tmp.csv', 'wb') as tmp:
    for item in zippedsimoutput:
        tmp.write("{0}\n".format(item))
c.execute("""LOAD DATA LOCAL INFILE 'tmp.csv' INTO TABLE flags FIELDS TERMINATED BY ',' ENCLOSED BY '"'  LINES TERMINATED BY '\r\n' ;""")

行は、データベースの列と同じ順序である必要があることに注意してください。

于 2012-08-06T18:03:37.830 に答える