数据库引擎的条件更改

时间:2019-04-02 06:03:46

标签: mysql

我想将数据库的表格式更改为InnoDB。但是我只希望在表格式不是InnoDB的情况下运行操作。

如果执行以下命令,则如果表格式已经是InnoDB,则一次又一次地执行耗时的操作(类似于修复):

ALTER TABLE `MyTable` ENGINE InnoDB;

如果目标格式已经是InnoDB,是否存在可以在这种情况下插入的条件,以便操作运行得更快?

我正在考虑类似的东西

ALTER TABLE `MyTable` ENGINE InnoDB WHERE ENGINE != 'InnoDB';
ALTER TABLE IGNORE `MyTable` ENGINE InnoDB;

1 个答案:

答案 0 :(得分:3)

您可以使用information_schema.TABLES来生成脚本:

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';

然后,您需要复制结果并执行。

Demo

更新

如果需要一次执行它,则可以在information_schema.TABLES上用光标定义一个存储过程并执行它:

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;