Ce qui suit est assez rapide, prend un peu plus de 6 minutes avec 10 millions de lignes mais la table d'exemple a moins de champs et d'index que votre table de production alors attendez-vous à ce que cela prenne un peu plus de temps dans votre cas si vous décidez de l'utiliser !
Remarque :l'exemple a été réalisé sur un système d'exploitation Windows, vous devrez donc modifier les noms de chemin et \r\n en \n pour vous conformer aux normes Linux !
Voici ma table existante (moteur InnoDB) :
drop table if exists customers;
create table customers
(
customer_id int unsigned not null auto_increment primary key,
name varchar(255) not null,
country_id tinyint unsigned not null default 0,
key (country_id)
)
engine=innodb;
mysql> select count(*) from customers;
+----------+
| count(*) |
+----------+
| 10000000 |
+----------+
1 row in set (1.78 sec)
Créez une nouvelle version du tableau qui inclut le nouveau champ dont vous avez besoin :
drop table if exists customers_new;
create table customers_new
(
customer_id int unsigned not null auto_increment primary key,
name varchar(255) not null,
country_id tinyint unsigned not null default 0,
split tinyint not null default 0,
key (country_id)
)
engine=innodb;
Rechercher l'emplacement de votre dossier Uploads :
select @@secure_file_priv;
Exporter les données dans l'ordre PK de l'ancienne table client au format csv :
select * into outfile 'C:\\ProgramData\\MySQL\\MySQL Server 8.0\\Uploads\\customers.dat'
fields terminated by '|' optionally enclosed by '"'
lines terminated by '\r\n'
from customers order by customer_id;
Query OK, 10000000 rows affected (17.39 sec)
Chargez le fichier customer.dat dans la nouvelle table client :
truncate table customers_new;
set autocommit = 0;
load data infile 'C:\\ProgramData\\MySQL\\MySQL Server 8.0\\Uploads\\customers.dat'
into table customers_new
fields terminated by '|' optionally enclosed by '"'
lines terminated by '\r\n'
(
customer_id,
name,
country_id,
@dummy -- represents the new split field
)
set
name = nullif(name,'');
commit;
Query OK, 10000000 rows affected (6 min 0.14 sec)
Confirmez que le nouveau tableau semble correct :
select * from customers_new order by customer_id desc limit 1;
+-------------+-------------------+------------+-------+
| customer_id | name | country_id | split |
+-------------+-------------------+------------+-------+
| 10000000 | customer 10000000 | 218 | 0 |
+-------------+-------------------+------------+-------+
1 row in set (0.00 sec)
insert into customers_new (name, country_id, split) values ('f00',1,1);
Query OK, 1 row affected (0.07 sec)
select * from customers_new order by customer_id desc limit 1;
+-------------+------+------------+-------+
| customer_id | name | country_id | split |
+-------------+------+------------+-------+
| 10000001 | f00 | 1 | 1 |
+-------------+------+------------+-------+
1 row in set (0.00 sec)
Supprimer l'ancienne table et renommer la nouvelle :
drop table customers;
Query OK, 0 rows affected (0.18 sec)
rename table customers_new to customers;
Query OK, 0 rows affected (0.05 sec)
select * from customers order by customer_id desc limit 1;
+-------------+------+------------+-------+
| customer_id | name | country_id | split |
+-------------+------+------------+-------+
| 10000001 | f00 | 1 | 1 |
+-------------+------+------------+-------+
1 row in set (0.00 sec)
C'est tout !