如何在每个模式中执行此脚本?

时间:2019-09-15 19:43:50

标签: mysql sql

我有这段代码可以对架构的每个表运行“优化表”。

但是,我需要将其运行到每个架构中的每个表。我该怎么做而不会引起问题?

set @a=null,@c=null,@b=concat("show tables where",ifnull(concat(" `Tables_in_",database(),"` like '",@c,"' and"),'')," (@a:=concat_ws(',',@a,`Tables_in_",database(),"`))");
Prepare `bd` from @b;
EXECUTE `bd`;
DEALLOCATE PREPARE `bd`;
set @a:=concat('optimize table ',@a);
PREPARE `sql` FROM @a;
EXECUTE `sql`;
DEALLOCATE PREPARE `sql`;
set @a=null,@b=null,@c=null;

1 个答案:

答案 0 :(得分:2)

这是为您目的的存储过程。

通过首先查询INFORMATION_SCHEMA.TABLES来检索模式和表名称的列表来工作。然后进入循环并依次执行OPTIMIZE TABLE命令。

重要说明:在 all 表上运行这样的命令可能不是一个好主意。具体来说,您不会(或无法)访问MySQL内置模式。我在查询中添加了WHERE子句,该子句排除了以下架构:information_schemaperformance_schemamysqlsys。我建议您进一步将WHERE子句限制为您的特定需求(拥有固定的模式列表将是一个好主意)。

DELIMITER $$

CREATE PROCEDURE OptimizeAllTables()
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE tableName CHAR(100);
    DECLARE tableSchema CHAR(100);

    DECLARE tableList CURSOR FOR 
        SELECT table_schema, table_name 
        FROM information_schema.tables 
        WHERE table_schema NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys');
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN tableList;
    tableListLoop: LOOP
        SET done = FALSE;

        FETCH tableList INTO tableSchema, tableName;
        IF done THEN
            LEAVE tableListLoop;
        END IF;

        SET @VarSQL = CONCAT('OPTIMIZE TABLE `', tableSchema, '`.`', tableName, '`');
        -- SELECT @VarSQL;
        PREPARE stmt FROM @VarSQL;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;

    END LOOP;
    CLOSE tableList;

END$$

我也强烈建议您在实际执行此程序之前,先在调试模式下运行此程序。为此,您可以更改此块:

    -- SELECT @VarSQL;
    PREPARE stmt FROM @VarSQL;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

收件人:

    SELECT @VarSQL;
    -- PREPARE stmt FROM @VarSQL;
    -- EXECUTE stmt;
    -- DEALLOCATE PREPARE stmt;

这将显示命令而不实际执行它们。

Demo on DB Fiddle (在调试模式下):

-- create a few tables for testing
create table table1(id int primary key);
create table table2(id int primary key);
create table table3(id int primary key);

-- call the procedure
call OptimizeAllTables();

收益:

| @VarSQL                        |
| ------------------------------ |
| OPTIMIZE TABLE `test`.`table1` |

| @VarSQL                        |
| ------------------------------ |
| OPTIMIZE TABLE `test`.`table2` |

| @VarSQL                        |
| ------------------------------ |
| OPTIMIZE TABLE `test`.`table3` |