Reputation: 3022
I would like to change the table format of my database to InnoDB. But I only want the action to run if the table format is not InnoDB yet.
If you execute the following command, a time-intensive action is started again and again (similar to a repair), if the table format is already InnoDB:
ALTER TABLE `MyTable` ENGINE InnoDB;
Is there a condition, which you can insert for this case, so that the operation runs faster, if the target format is already InnoDB?
I'm thinking about something like:
ALTER TABLE `MyTable` ENGINE InnoDB WHERE ENGINE != 'InnoDB';
ALTER TABLE IGNORE `MyTable` ENGINE InnoDB;
Upvotes: 1
Views: 82
Reputation: 31812
You can use information_schema.TABLES
, to generate the script:
set @db_schema = 'test';
set @alter_query = 'alter table `{table}` engine=innodb;';
select group_concat(replace(
@alter_query,
'{table}',
replace(t.TABLE_NAME, '`', '``')
) separator '\n') as script
from information_schema.TABLES t
where t.TABLE_SCHEMA = @db_schema
and t.ENGINE = 'MyISAM';
Then you need to copy the result and execute it.
If you need to execute it in one run, you can define a stored procedure with a cursor on information_schema.TABLES
and execute it:
drop procedure if exists tmp_alter_myisam_to_innodb;
delimiter //
create procedure tmp_alter_myisam_to_innodb(in db_name text)
begin
declare done int default 0;
declare tbl text;
declare cur cursor for
select t.TABLE_NAME
from information_schema.TABLES t
where t.TABLE_SCHEMA = db_name
and t.ENGINE = 'MyISAM';
declare continue handler for not found set done = 1;
open cur;
fetch_loop: loop
fetch cur into tbl;
if done then
leave fetch_loop;
end if;
set @stmt = 'alter table `{table}` engine=innodb;';
set tbl = replace(tbl, '`', '``');
set @stmt = replace(@stmt, '{table}', tbl);
prepare stmt from @stmt;
execute stmt;
deallocate prepare stmt;
end loop;
close cur;
end //
delimiter ;
call tmp_alter_myisam_to_innodb('my_db');
drop procedure tmp_alter_myisam_to_innodb;
Upvotes: 3