Description
I have 2 tables with the following structure (irrelevant columns removed):
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)
and
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)
Table parts
contains 184147 rows, and details
contains 7278870 rows.
The part_code
column from details
represents the code
column from the parts
table.
Since these columns are varchar
, I want to add the column id int(11)
to parts
, and part_id int(11)
to details
. I tried this:
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)
So now I have the id column with correct data in parts
table. After adding part_id
column to details
table:
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
Now the big problem is how to update part_id
accordingly? The following query:
mysql> update details d
join parts p on d.part_code = p.code
set d.part_id = p.id;
was running for about 30 hours until I killed it.
Note that both tables are 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)
I just now realized that one of the problems was that dropping the key on parts
table I dropped the index on the code
column. On the other side, I have the following indexes on details
table (some irrelevant columns are omitted):
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)
My questions are:
- Is the update query OK or it can be optimized somehow?
- I will add the index on the
code
column inparts
table, will the query run in a reasonable time, or it will run for days again? - How can I make a (sql/bash/php) script so I can see the progress of the query execution?
Thank you very much!