Here is a stored procedure for your purpose.
It works by first querying INFORMATION_SCHEMA.TABLES
to retrieve the list of schemas and table names. Then it goes into a loop and executes the OPTIMIZE TABLE
commands sequentially.
Important note: running such a command on all tables is probably not a good idea. Specifically, you don't (or can't) adress MySQL built-in schemas. I added a WHERE
clause in the query that excludes the following schemas: information_schema
, performance_schema
, mysql
and sys
. I would suggest that you further restrict the WHERE
clause to your specific need (having a fixed list of schema would be a good idea).
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$$
I would also strongly suggest that you run this procedure in debug mode before executing it for real. For this, you can change this block:
-- SELECT @VarSQL;
PREPARE stmt FROM @VarSQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
To:
SELECT @VarSQL;
-- PREPARE stmt FROM @VarSQL;
-- EXECUTE stmt;
-- DEALLOCATE PREPARE stmt;
This will show the commands without actually executing them.
Demo on DB Fiddle (in debug mode):
-- 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();
Yields:
| @VarSQL |
| ------------------------------ |
| OPTIMIZE TABLE `test`.`table1` |
| @VarSQL |
| ------------------------------ |
| OPTIMIZE TABLE `test`.`table2` |
| @VarSQL |
| ------------------------------ |
| OPTIMIZE TABLE `test`.`table3` |