0

mysqlの挿入が非常に遅いことに気付きました。テストとデモンストレーションのために、次の表を使用しました。

+----------+-----------------------------------------------+
| Table    | Create Table                                  |
+----------+-----------------------------------------------+
| ik_b64_8 | CREATE TABLE `incr_tbl` (
  `cnt` int(11) NOT NULL,
  PRIMARY KEY (`cnt`)
) ENGINE=InnoDB DEFAULT CHARSET=ascii COLLATE=ascii_bin |
+----------+-----------------------------------------------+

およびPythonコード:

def profile_basic(cnt):
    db = database.Connection("localhost","testing_delme","root", "")
    t1 = time.time()
    for ii in range(cnt):
        db.execute("INSERT INTO testing_delme.incr_tbl VALUES (%s)", ii)
    print time.time() - t1

この挿入専用コードを空のテーブルで実行すると、1K挿入に65秒かかります。私はinnodb_flush_log_at_trx_commit=1を持っていますが、テーブルにはデータを失う余裕がないため、これが必要です。私の質問は、このセットを使用すると、挿入が非常に遅くなる可能性があるということです。それとも私は何か他のものを逃していますか?

4

3 に答える 3

1

「データを失うわけにはいきません。」それは程度の問題です。フラッシュしないと、データの最後の 1 秒が失われる可能性があります。フラッシュすると、その時点で書き込まれていたものだけが失われる可能性があります。あなたは本当にそれ以上の大きなパフォーマンスヒットを取りたいですか?

また、ディスクが破損した場合、前回のバックアップ以降のすべてのデータが失われます。これは長期的には避けられず、より多くのデータに関係するため、頻繁にバックアップを作成することについてより心配します.

フラッシングを無効にします。すべてのディスク アクティビティのため、挿入ごとに数百ミリ秒ではないにしても、簡単に数十ミリ秒かかると思います。テーブルにいくつかのインデックスがあると、さらに悪化します。

これらすべてにもかかわらず、すべての書き込みで絶対にフラッシュする必要がある場合は、データベースを SSD に配置すると、パフォーマンスが大幅に向上することもわかります。

于 2012-05-01T20:30:19.507 に答える
0

db.execute()1つずつ挿入すると、非常に遅くなります。ループを使用してリストを作成し、一括挿入を 1 回実行します。db.executemany()

def profile_basic(cnt):
    import mysql.connector, time
    cnx = mysql.connector.connect("localhost","testing_delme","root", "")
    db = cnx.cursor()
    list_ii = []
    t1 = time.time()
    for ii in range(cnt):
        list_ii.append(ii)
    # One bulk insert
    db.executemany("INSERT INTO testing_delme.incr_tbl VALUES (%s)", list_ii)
    # Don't forget to commit
    db.commit()
    print time.time() - t1 
于 2015-02-15T07:36:11.073 に答える
0

1 秒あたりのトランザクション数の制限に達したと思います。各挿入は個別のトランザクションとして扱われるため、自動コミット モードにする必要があります。

(1) 1 つの SQL ステートメントに多くの行を挿入しても問題ありません。

insert into incr_tbl values (1),(2),(3)....

同等の Python は次のようなものです。

db.execute("insert into incr_tbl values %s" % ",".join(["(%s)" % i for i in range(xx)]))

(2) または、トランザクションを明示的に開始することもできます。

db = ...(autocommit=False)
db.begin_transaction()
for i in xx: db.execute(... insert i ...)
db.commit()

適切なサーバーを使用している場合、tx レートは 1 秒あたり 15 よりもはるかに高くなるはずです。そのため、マシンと mysql の設定を確認してください。ディスクにコミットして毎回待機しても(sqlite)、市販のハードドライブで100 tx / sになるはずです。データベースが USB フラッシュに配置されている場合にのみ、この低いレートが見られました。別の考えられる説明は、Python がデータベースから非常に離れており、ネットワークの遅延がパフォーマンスを低下させていることです。この場合、(1) は役立ちますが、(2) は役に立ちません。

于 2012-12-20T12:52:57.400 に答える