大規模な MySQL データベースで作業しており、特定のテーブルでの INSERT パフォーマンスを改善する必要があります。これには約 2 億行が含まれており、その構造は次のとおりです。
(少し前提:私はデータベースの専門家ではないので、私が書いたコードは間違った基盤に基づいている可能性があります。私の間違いを理解するのを手伝ってください:))
CREATE TABLE IF NOT EXISTS items (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(200) NOT NULL,
key VARCHAR(10) NOT NULL,
busy TINYINT(1) NOT NULL DEFAULT 1,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id, name),
UNIQUE KEY name_key_unique_key (name, key),
INDEX name_index (name)
) ENGINE=MyISAM
PARTITION BY LINEAR KEY(name)
PARTITIONS 25;
毎日、各行が "name;key" のペアで構成される多数の csv ファイルを受け取るため、これらのファイルを解析し (各行に created_at と updated_at の値を追加)、値をテーブルに挿入する必要があります。この例では、「名前」と「キー」の組み合わせは一意でなければならないため、次のように挿入手順を実装しました。
CREATE TEMPORARY TABLE temp_items (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(200) NOT NULL,
key VARCHAR(10) NOT NULL,
busy TINYINT(1) NOT NULL DEFAULT 1,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id)
)
ENGINE=MyISAM;
LOAD DATA LOCAL INFILE 'file_to_process.csv'
INTO TABLE temp_items
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '\"'
(name, key, created_at, updated_at);
INSERT INTO items (name, key, busy, created_at, updated_at)
(
SELECT temp_items.name, temp_items.key, temp_items.busy, temp_items.created_at, temp_items.updated_at
FROM temp_items
)
ON DUPLICATE KEY UPDATE busy=1, updated_at=NOW();
DROP TEMPORARY TABLE temp_items;
先ほど示したコードで目標を達成できましたが、実行を完了するには約 48 時間かかり、これが問題です。このパフォーマンスの低下は、スクリプトが非常に大きなテーブル (2 億行) をチェックする必要があり、挿入ごとに "name;key" のペアが一意であることが原因であると思います。
スクリプトのパフォーマンスを向上させるにはどうすればよいですか?
事前にすべてに感謝します。