2009-10-19 7 views
5

巨大なデータソース(20GBの生のテキスト)を掘り起こし、単純な空白のテーブル(1つの主キーを持つ4つの整数列)で実行するINSERTのロードを生成するCプログラムがあります。 MEMORYテーブルとして設定すると、タスク全体が8時間で完了します。終了後、テーブルには約1億5,000万行が存在します。 8時間は私にとって完全にまともな数字です。これは1回限りの取引です。大規模な150M行MySQLテーブルの生成

テーブルをMyISAMに変換しようとすると、(A)他のプロセス用にメモリを解放し、(B)コンピュータを再起動してもデータが消去されないようにするときに問題が発生します。

ALTER TABLE memtable ENGINE = MyISAM 

私は今、2日間にわたるこのALTER TABLEクエリ実行させてきた、そしてそれが行われていません。私は今それを殺しました。

テーブルをMyISAMとして最初に作成すると、書き込み速度が非常に悪いように見えます(特に、クエリでON DUPLICATE KEY UPDATEテクニックを使用する必要があるため)。一時的にキーをオフにすることはできません。テーブルを1000倍以上大きくすると、キーを再処理して基本的にGROUP BYを150,000,000,000行で実行する必要があります。うーん、いいえ。

実現する重要な制約の1つ:主キー(ハッシュ)がすでにテーブルに存在する場合は、INSERTクエリのUPDATEレコードです。

MyISAMを厳密に使用しようとする試みの冒頭で、毎秒1,250行の大雑把な速度が得られます。インデックスが成長すると、私はこの金利がさらに上昇すると考えています。


私はマシンに16GBのメモリを搭載しています。ディスク上のインデックス付きMyISAMテーブルとして最終的に終わる膨大なテーブルを生成する最適な方法は何ですか?


明確化:クエリ(INSERT ... ON DUPLICATE KEY UPDATE val=val+whatever)から起こって、多くの、多くのアップデートがあります。これは決して、生のダンプの問題ではありません。最初にMEMORYテーブルを試してみる理由は、すべてのINSERTで発生するすべてのインデックス検索とテーブル変更を高速化するためでした。

答えて

1

残念ながら、あなたにコメントを投げかけてください(おそらく最後のもの)。

大きなテーブルをMyISAMからInnoDBに変換する例を示したのがthis articleでした。これはあなたがやっていることではありませんが、中間のメモリテーブルを使用し、メモリからInnoDBへの効率的な移行を説明しています - InnoDBがそれが最終的に注文されることを期待する方法でメモリ内のテーブルを注文する。 MyISAMに縛られていないのであれば、すでに「正しい」メモリテーブルが構築されているので一見価値があるかもしれません。

+0

InnoDBは問題ありません。これはとても巧妙です...私はそれが好きです。私にコメントを投げてくれてありがとう。それは有り難いです。 :) – brianreavis

3

あなたがMyISAMテーブルにするつもりなら、なぜ最初にメモリにそれを作成していますか?速度だけであれば、MyISAMテーブルへの変換は、それをメモリに作成して開始することで速度の向上を無効にすると考えています。

「ディスク上の」テーブルに直接挿入するのは遅すぎます(現在の方法には日数がかかると判断しているかどうかわかりませんが)、オフにしたり削除したりすることができます一意性制約を使用し、後で一意性を再確立するためにDELETEクエリを使用してから、その制約を再度有効化/追加します。私は過去にINNODBテーブルにインポートするときにこの手法を使用しましたが、後で削除すると全体的にははるかに高速でした。

また、INSERTステートメントの代わりにCSVファイルを作成し、LOAD DATA INFILEを使用してテーブルにロードすることもできます(挿入が高速ですが、現在参照が見つかりません)。必要に応じてCSV storage engine経由で直接ご利用いただけます。

+0

質問をいくつかお答えしました。私は、CSVの挿入が速く実行されていると主張しているソースを見つけましたが、データを数ギガバイトのCSV **にダンプしてから、データベースにロードするのがかなり賢明です。これは、問題のハードドライブI/Oが非常に遅いということです。 – brianreavis

+0

しかし、あなたはINSERTのセットを使ってSQLファイルにダンプしています。とにかくあなたはそうではありません。私はCSVファイルがどのように異なったIOの賢明さを見ていないのですか? MyISAMへの読み込みが遅すぎるという問題を修正するかもしれない別の方法を説明する段落を追加しました。 –

+0

一意制約を削除できません。私は 'ON DUPLICATE KEY UPDATE'を使用して、主キー(ハッシュ)がすでに存在する場合にレコードを更新します。制約を削除すると、テーブルのサイズが1000倍を超える可能性があります(それはあまり意味がありません)。大量のUPDATEが行われています---データベースへの生のダンプだけではありません。 – brianreavis

1

私はmysqlを使用せず、SQLサーバーを使用していますが、これは私が同様のサイズのファイルを処理するために使用するプロセスです。まず、制約がないステージングテーブルにファイルをダンプします。次に、ステージングテーブルからdupsを特定して削除します。次に、一致する可能性のある既存のレコードを検索し、IDテーブルをステージングテーブルの列に挿入します。次に、idフィールドの列がnullでない場所を更新し、nullの場所に挿入します。私がステージングテーブルのdupsを取り除くすべての作業を行う理由の1つは、実行するときにprodテーブルへの影響が少ないことを意味します。私のプロセス全体は1時間もかからずに実行されます(実際には、データを非正規化してデータを消去する必要があるため、実際には説明した以上に多くの時間がかかります)。制約を調整したり、インデックスを削除したり、prodテーブルにヒットする前に処理の大部分を行ったりしているので、私は悩む必要はありません。

simliarプロセスがうまくいくかどうかを検討してください。また、行単位で作業するのではなく、ステージングテーブルにrawデータを取得するために何らかのバルクインポートを使用できますか(約16分でステージングする22GBのファイルをプルします)

関連する問題