Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
857 views
in Technique[技术] by (71.8m points)

mysql slow query

ALTER TABLE customers ADD split INT(1);

10 mil. records... I performed this command for 1 hour and still loading ..is there any way to make it finish faster ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The following is pretty quick, takes a little over 6 minutes with 10 million rows but the example table has fewer fields and indexes than your production table so expect it to take a little longer in your case if you decide to use it !

Note: the example was done on windows OS so you'll have to change pathnames and to to conform to linux standards !

Here's my existing table (InnoDB engine):

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)

Create a new version of the table which includes the new field you require:

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;

Find the location of your Uploads folder:

select @@secure_file_priv;

Export the data in PK order from the old customer table into csv format:

select * into outfile 'C:\ProgramData\MySQL\MySQL Server 8.0\Uploads\customers.dat'
fields terminated by '|' optionally enclosed by '"'
lines terminated by '
'
from customers order by customer_id;

Query OK, 10000000 rows affected (17.39 sec)

Load the customer.dat file into the new customer table:

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 '
'
(
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)

Confirm that the new table looks okay:

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)

Drop the old table and rename new one:

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)

That's all folks !


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...