Reputation: 7033
I have a table with 9918751 records in it, please find below is data structure,
+--------------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| start_ip | varchar(32) | YES | UNI | NULL | |
| end_ip | varchar(32) | YES | UNI | NULL | |
| country | varchar(255) | YES | | NULL | |
| region | varchar(255) | YES | | NULL | |
| city | varchar(255) | YES | | NULL | |
| country_conf | varchar(255) | YES | | NULL | |
| region_conf | varchar(255) | YES | | NULL | |
| city_conf | varchar(255) | YES | | NULL | |
| country_code | int(11) | YES | | NULL | |
| region_code | int(11) | YES | | NULL | |
| city_code | int(11) | YES | | NULL | |
| two_letter_country | varchar(20) | YES | | NULL | |
| creation_datetime | timestamp | NO | | CURRENT_TIMESTAMP | |
+--------------------+--------------+------+-----+-------------------+----------------+
In my table the start_ip
and end_ip
column contains valid IPv4 IP Address(like 192.168.1.1
, 12.23.34.22
etc), Now I want to update all rows(9918751) to convert the IP address to integer using INET_ATON()
function. When I am running below query
update geo_location_info set start_ip = INET_ATON(start_ip);
This query was taking too much time as to update the 9918751 rows and it was not completing the update. Please let me know any alternative (store procedure ?)
Upvotes: 1
Views: 232
Reputation: 1270401
The basic idea is to use a loop for the update. The problem is that the function call takes a while and queries can time out. In addition, updating almost 10 million rows puts a certain burden on the logging mechanisms for maintaining data integrity. Assuming the id
is the populated incrementally, you might do this in groups of 10,000 or maybe 100,000. Unfortunately, you can't really use @Stewarts idea, but almost half of all the rows are likely to start with 1
.
The basic loop is:
set @len := 10000, @i := 1;
while @i * @len < 10000000 do
update geo_location_info
set start_ip = INET_ATON(start_ip)
where id between @len*@i and @len*(@i + 1) - 1;
set @i := @i + 1;
end while;
Unfortunately, in MySQL, you need to put this into a stored procedure -- because control flow mechanisms (such as while
) are only allowed in stored programs. So, something more like:
delimiter $$
create procedure do_update ()
begin
set @len := 10000, @i := 1;
select @max := max(id) from geo_location_info;
while @i * @len <= @max do
update geo_location_info
set start_ip = INET_ATON(start_ip)
where id between @len*@i and @len*(@i + 1) - 1;
set @i := @i + 1;
end while;
end $$
delimiter ;
Upvotes: 2