DDL 先読みは、インデックス構築スキャンが到達する前にデータページをプリフェッチすることにより、大規模テーブルにおける DDL 操作の実行を高速化し、操作中の I/O 待ち時間を削減します。
大規模テーブルに対して ALTER TABLE 文を実行すると、InnoDB はインデックスの再構築や行の再構造化のために、すべてのデータページを逐次読み込みます。DDL 先読みでは、スキャンの進行に先立ってページをプリフェッチすることで、必要なタイミングですでにページが利用可能となるようにします。
前提条件
開始する前に、PolarDB クラスターが以下のいずれかのバージョン要件を満たしていることを確認してください。
PolarDB for MySQL 8.0:リビジョンバージョン 8.0.1.1.28 以降
PolarDB for MySQL 5.7:リビジョンバージョン 5.7.1.0.22 以降
PolarDB for MySQL 5.6:リビジョンバージョン 5.6.1.0.34 以降
クラスターのリビジョンバージョンを確認するには、「エンジンバージョンの照会」をご参照ください。
I/O 影響とスケジューリング
DDL 先読みは、ページのプリフェッチ専用に追加のスレッドを割り当てることで、DDL 操作の実行期間中に I/O 消費量を増加させます。この追加の I/O 負荷は、同時実行中の SQL ワークロードに影響を与える可能性があります。本番トラフィックへの影響を最小限に抑えるため、DDL 先読みは非ピーク時間帯に実行してください。
パラメーター
DDL 先読みを有効化し、プリフェッチ量を調整するには、以下の 2 つのグローバルパラメーターを使用します。
loose_innodb_polar_ddl_build_index_readahead
| パラメーター | レベル | デフォルト | 有効な値 | 説明 |
|---|---|---|---|---|
loose_innodb_polar_ddl_build_index_readahead | グローバル | OFF | ON、OFF | DDL 先読みの有効/無効を設定します。 |
loose_innodb_polar_ddl_build_index_readahead_page_num
| パラメーター | レベル | デフォルト | 有効な値 | 説明 |
|---|---|---|---|---|
loose_innodb_polar_ddl_build_index_readahead_page_num | グローバル | 64 | 32~256 | 1 回のプリフェッチ要求で読み込むページ数です。各ページは 16 KB です。値を大きくすると 1 回の要求でより多くのデータがプリフェッチされ、大規模な逐次スキャンに有効ですが、I/O 帯域幅の消費量も増加します。 |
初期値として 64 ページ(1 回のプリフェッチあたり 1 MB)から開始してください。DDL スキャンがクラスター全体の I/O 消費の主因であり、かつクラスターに十分な I/O 余力がある場合など、極めて大規模なテーブルでは、256 ページ(1 回のプリフェッチあたり 4 MB)まで値を増加させることを推奨します。
パフォーマンステスト
以下のベンチマークでは、DDL 先読みを有効化した場合と無効化した場合の DDL 実行時間を比較しています。
テスト環境
PolarDB for MySQL 8.0、CPU コア数 8、メモリ 32 GB
ストレージ容量:50 TB
スキーマ
CREATE TABLE `table_1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`seller_id` bigint(20) DEFAULT NULL,
`seller_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`gmt_create` varchar(30) DEFAULT NULL,
`update_time` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;テストデータ
以下のストアドプロシージャを使用して、1 億行を挿入します。
delimiter ||
CREATE PROCEDURE populate_0(IN NUM INT)
BEGIN
DECLARE sid INT;
DECLARE suffix_name INT;
DECLARE i INT;
SET sid=1000;
SET suffix_name=10;
SET i=1;
START TRANSACTION;
WHILE i <= NUM
DO
INSERT INTO table_1(seller_id,seller_name,gmt_create,update_time) VALUES(sid,CONCAT('sellername',suffix_name),NOW(),NOW());
SET suffix_name=suffix_name+1;
SET sid=sid+1;
SET i=i+1;
END WHILE;
COMMIT;
END ||
delimiter ;
CALL populate_0(100000000);各テストを実行する前に PolarDB プロセスを再起動し、バッファープールキャッシュをクリアしてください。これにより、結果はキャッシュされたデータではなくディスク I/O のパフォーマンスを正確に反映します。
結果
DDL 先読みを有効化する場合、すべてのテストで loose_innodb_polar_ddl_build_index_readahead_page_num=256 を使用しています。
ALTER TABLE table_1 ADD INDEX name_index (seller_name):
| DDL 先読み | 所要時間(秒) |
|---|---|
| 無効 | 485 |
| 有効 | 412 |
ALTER TABLE table_1 ADD COLUMN c1 varchar(100) after id:
| DDL 先読み | 所要時間(秒) |
|---|---|
| 無効 | 264 |
| 有効 | 159 |
お問い合わせ
DDL 操作についてご質問がある場合は、テクニカルサポート までお問い合わせください。
次のステップ
お問い合わせ:PolarDB 上での DDL 操作についてご質問がある場合