1

私はデータ移行を行っており、以下のコードをいくつかの場所で行っています。それはいくつかのbashのものから何とか移行されたので動作しますが、mysqlモジュールを使用する方が効率的かどうか疑問に思っています。ありがとう。

    p1 = Popen(["echo", query], stdout=PIPE, close_fds=True)

    p2 = Popen(["mysql", "--host=host", "--port=3999",
        "-u", "user", "--password=foo", "--protocol=TCP"],
        stdin=p1.stdout, stdout=PIPE, close_fds=True)

    p1.stdout.close()

`

p1 = Popen(["echo", "show columns from %s" % (table)], stdout=PIPE,
        close_fds=True)

p2 = Popen(["mysql", "--host=host", "--port=3999",
    "-u", "user", "--password=foo", "--protocol=TCP"],
    stdin=p1.stdout, stdout=PIPE, close_fds=True)

p3 = Popen(["awk", "{print $1}"], stdin=p2.stdout, stdout=PIPE,
        close_fds=True)
4

1 に答える 1

3

それはあなたが何をしようとしているのかによります。結果をPythonで処理する必要がない場合は、実際にはサブプロセスを使用する方が高速な場合があります。

ここに画像の説明を入力してください

このグラフでは、y軸は秒単位で、x軸は選択されたデータの行数を表します。

比較は完全に公平ではないことに注意してください 。using_subprocess文字列をusing_mysqldb返し、タプルのリストを返します。PythonがそれらのPythonオブジェクトを作成するのにかかる追加の時間は、確かに速度の違いの少なくとも一部を説明しています。


を使用してPythonでシェルスタイルのスクリプトを作成する理由はありませんsubprocess。シェルスクリプトを書くだけの方がいいかもしれません。

Pythonを使用して、によって返される文字列を処理する必要がある場合は、。ではなく、 shモジュールmysqlを使用してコードをはるかに読みやすくすることができます。subprocess


import config
import subprocess
import shlex
import timeit
import MySQLdb
import collections
import matplotlib.pyplot as plt

Popen = subprocess.Popen
PIPE = subprocess.PIPE
sql = 'select * from table limit {n}'

def using_subprocess(n):
    p1 = Popen(
        shlex.split(
            'echo {s}'.format(s=sql.format(n=n))), stdout=PIPE, close_fds=True)

    p2 = Popen(
        shlex.split(
            'mysql --host={h} -u {u} --password={p} --database={d}'.format(
                h=config.HOST,
                u=config.USER,
                p=config.PASS,
                d=config.MYDB
                )),
        stdin=p1.stdout, stdout=PIPE, close_fds=True)

    p1.stdout.close()
    out, err = p2.communicate()
    return out

def using_mysqldb(n):
    connection = MySQLdb.connect(
        host = config.HOST, user = config.USER,
        passwd = config.PASS, db = config.MYDB)
    cursor = connection.cursor()

    cursor.execute(sql.format(n=n))
    rows = cursor.fetchall()
    return rows

times = collections.defaultdict(list)
ns = [10**i for i in range(5)]
for n in ns:
    times['using_mysqldb'].append(
        timeit.timeit('m.using_mysqldb({n})'.format(n=n),
                      'import __main__ as m',
                      number = 10))
    times['using_subprocess'].append(
        timeit.timeit('m.using_subprocess({n})'.format(n=n),
                      'import __main__ as m',
                      number = 10))

for name, time in times.iteritems():
    plt.plot(ns, time, label=name)
    # print('{n}: {t}'.format(n=name, t=time))
plt.legend(loc='best')
plt.show()    
于 2013-03-17T03:13:56.230 に答える