2

MySQL データベース (InnoDB エンジン) にインポートされている、約 400 GB の大量のプレーン テキスト ファイルのセットがあります (私が考えていること)。.txt ファイルのサイズは 2GB から 26GB で、各ファイルはデータベース内のテーブルを表します。.txt ファイルを解析して SQL ステートメントを作成する Python スクリプトが与えられました。私は、次の仕様のこのタスク専用のマシンを持っています。

  • OS - Windows 10
  • 32GBのRAM
  • 4TBのハードドライブ
  • i7 3.40 GHz プロセッサー

このインポートを最適化して、可能な限り迅速かつダーティにしたいと考えています。スタック O の質問MySQL ドキュメント、およびその他のソースに基づいて、MySQL my.ini ファイルの次の構成設定を変更しました。

max_allowed_packet=1073741824;

autocommit=0;

net_buffer_length=0;

foreign_key_check=0;

unique_checks=0;

innodb_buffer_pool_size=8G; (this made a big difference in speed when I increased from the default of 128M)

マシンのリソースのかなりの部分を使用するように MySQL に指示する、私が見逃した構成ファイルの他の設定 (ログやキャッシュに関するものかもしれません) はありますか? 私が見逃している別のボトルネックはありますか?

(サイドノート: これが関連しているかどうかはわかりません - インポートを開始すると、mysqldプロセスがスピンアップしてシステムのメモリの約 13-15% を使用しますが、Python スクリプトがインポートを続行するのを停止すると、プロセスは決してパージされないようです。 . これはログとフラッシュの設定をいじった結果なのだろうか. 事前に助けてくれてありがとう.)

編集

テーブルにデータを入力する Python スクリプトの関連部分を次に示します。スクリプトは、50,000 レコードごとに接続、コミット、および接続を閉じているようです。関数の最後にあるを削除してconn.commit()、MySQL にコミットを処理させることはできますか? 以下のコメントwhile (true)はスクリプトの作成者からのもので、max_allowed_pa​​cket サイズを超えないようにその数を調整しました。

    conn = self.connect()

    while (True):
        #By default, we concatenate 200 inserts into a single INSERT statement.
        #a large batch size per insert improves performance, until you start hitting max_packet_size issues.
        #If you increase MySQL server's max_packet_size, you may get increased performance by increasing maxNum
        records = self.parser.nextRecords(maxNum=50000)
        if (not records):
            break

        escapedRecords = self._escapeRecords(records) #This will sanitize the records
        stringList = ["(%s)" % (", ".join(aRecord)) for aRecord in escapedRecords]

        cur = conn.cursor()
        colVals = unicode(", ".join(stringList), 'utf-8')
        exStr = exStrTemplate % (commandString, ignoreString, tableName, colNamesStr, colVals)
        #unquote NULLs
        exStr = exStr.replace("'NULL'", "NULL")
        exStr = exStr.replace("'null'", "NULL")

        try:
            cur.execute(exStr)
        except MySQLdb.Warning, e:
            LOGGER.warning(str(e))
        except MySQLdb.IntegrityError, e:
        #This is likely a primary key constraint violation; should only be hit if skipKeyViolators is False
            LOGGER.error("Error %d: %s", e.args[0], e.args[1])
        self.lastRecordIngested = self.parser.latestRecordNum
        recCheck = self._checkProgress()
        if recCheck:
            LOGGER.info("...at record %i...", recCheck)
    conn.commit()
    conn.close()
4

0 に答える 0