説明
次の構造の2つのテーブルがあります(無関係な列が削除されています)。
mysql> explain parts;
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| code | varchar(32) | NO | PRI | NULL | |
| slug | varchar(255) | YES | | NULL | |
| title | varchar(64) | YES | | NULL | |
+-------------+--------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
と
mysql> explain details;
+-------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+-------+
| sku | varchar(32) | NO | PRI | NULL | |
| description | varchar(700) | YES | | NULL | |
| part_code | varchar(32) | NO | PRI | | |
+-------------------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
テーブルparts
には184147行が含まれ、7278870行がdetails
含まれています。fromの列は、テーブルのpart_code
列をdetails
表します。これらの列はであるため、列を、およびに追加します。私はこれを試しました:code
parts
varchar
id int(11)
parts
part_id int(11)
details
mysql> alter table parts drop primary key;
Query OK, 184147 rows affected (0.66 sec)
Records: 184147 Duplicates: 0 Warnings: 0
mysql> alter table parts add column
id int(11) not null auto_increment primary key first;
Query OK, 184147 rows affected (0.55 sec)
Records: 184147 Duplicates: 0 Warnings: 0
mysql> select id, code from parts limit 5;
+----+-------------------------+
| id | code |
+----+-------------------------+
| 1 | Yhk0KqSMeLcfH1KEfykihQ2 |
| 2 | IMl4iweZdmrBGvSUCtMCJA2 |
| 3 | rAKZUDj1WOnbkX_8S8mNbw2 |
| 4 | rV09rJ3X33-MPiNRcPTAwA2 |
| 5 | LPyIa_M_TOZ8655u1Ls5mA2 |
+----+-------------------------+
5 rows in set (0.00 sec)
これで、parts
テーブルに正しいデータを含むid列ができました。テーブルにpart_id
列を追加した後:details
mysql> alter table details add column part_id int(11) not null after part_code;
Query OK, 7278870 rows affected (1 min 17.74 sec)
Records: 7278870 Duplicates: 0 Warnings: 0
さて、大きな問題はそれに応じてどのように更新part_id
するかです。次のクエリ:
mysql> update details d
join parts p on d.part_code = p.code
set d.part_id = p.id;
私がそれを殺すまで約30時間走っていました。
両方のテーブルがMyISAMであることに注意してください。
mysql> select engine from information_schema.tables where table_schema = 'db_name' and (table_name = 'parts' or table_name = 'details');
+--------+
| ENGINE |
+--------+
| MyISAM |
| MyISAM |
+--------+
2 rows in set (0.01 sec)
問題の1つは、テーブルにキーをドロップすると、列parts
にインデックスがドロップされることであることに気づきました。code
反対側では、details
テーブルに次のインデックスがあります(一部の無関係な列は省略されています)。
mysql> show indexes from details;
+---------+------------+----------+--------------+-------------+-----------+-------------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Index_type |
+---------+------------+----------+--------------+-------------+-----------+-------------+------------+
| details | 0 | PRIMARY | 1 | sku | A | NULL | BTREE |
| details | 0 | PRIMARY | 3 | part_code | A | 7278870 | BTREE |
+---------+------------+----------+--------------+-------------+-----------+-------------+------------+
2 rows in set (0.00 sec)
私の質問は次のとおりです。
- 更新クエリはOKですか、それとも何らかの方法で最適化できますか?
code
テーブルの列にインデックスを追加しparts
ますか、クエリは妥当な時間で実行されますか、それとも数日間実行されますか?- (sql / bash / php)スクリプトを作成して、クエリ実行の進行状況を確認するにはどうすればよいですか?
どうもありがとうございます!