I was wondering if there's a way to check if an index exists before creating it or destroying it on MySQL. It appears that there was a feature request for this a few years back, but I can't find any documentation for a solution. This needs to be done in a PHP app using MDB2.
To drop a non-primary key index, use the DROP INDEX command: DROP INDEX index_name ON table_name; The syntax requires the table name to be specified because MySQL allows index names to be reused on multiple tables.
Check INFORMATION_SCHEMA first. SELECT COUNT(1) IndexIsThere FROM INFORMATION_SCHEMA. STATISTICS WHERE table_schema=DATABASE() AND table_name='mytable' AND index_name='index_name'; If IndexIsThere is 0, you can create in the index.
If columns are dropped from a table, the columns are also removed from any index of which they are a part. If all columns that make up an index are dropped, the index is dropped as well.
Here is my 4 liner:
set @exist := (select count(*) from information_schema.statistics where table_name = 'table' and index_name = 'index' and table_schema = database());
set @sqlstmt := if( @exist > 0, 'select ''INFO: Index already exists.''', 'create index i_index on tablename ( columnname )');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
IF EXISTS
modifier is not built for DROP INDEX
or CREATE INDEX
yet. But you can check manually for the existence before creating/dropping an index.
Use this sentence to check whether the index already exists.
SHOW INDEX FROM table_name WHERE KEY_NAME = 'index_name'
Here is a DROP INDEX IF EXISTS procedure:
DELIMITER $$
DROP PROCEDURE IF EXISTS drop_index_if_exists $$
CREATE PROCEDURE drop_index_if_exists(in theTable varchar(128), in theIndexName varchar(128) )
BEGIN
IF((SELECT COUNT(*) AS index_exists FROM information_schema.statistics WHERE TABLE_SCHEMA = DATABASE() and table_name =
theTable AND index_name = theIndexName) > 0) THEN
SET @s = CONCAT('DROP INDEX ' , theIndexName , ' ON ' , theTable);
PREPARE stmt FROM @s;
EXECUTE stmt;
END IF;
END $$
DELIMITER ;
This code was created based on the procedure from here: Determining if MySQL table index exists before creating
I tweaked answers found here and else where to come up with the following sprocs for dropping & creating indexes. Note that the AddTableIndex sproc can drop the index if need be. They also accept a schema name which was critical for my uses.
DELIMITER //
DROP PROCEDURE IF EXISTS migrate.DropTableIndex //
CREATE PROCEDURE migrate.DropTableIndex
(
in schemaName varchar(128) -- If null use name of current schema;
, in tableName varchar(128) -- If null an exception will be thrown.
, in indexName varchar(128) -- If null an exception will be thrown.
)
BEGIN
SET schemaName = coalesce(schemaName, schema());
IF((SELECT COUNT(*) AS index_exists FROM information_schema.statistics WHERE TABLE_SCHEMA = schemaName and table_name = tableName AND index_name = indexName) > 0) THEN
SET @s = CONCAT('DROP INDEX `' , indexName , '` ON `' , schemaName, '`.`', tableName, '`');
PREPARE stmt FROM @s;
EXECUTE stmt;
END IF;
END //
DROP PROCEDURE IF EXISTS migrate.AddTableIndex//
CREATE PROCEDURE migrate.AddTableIndex
(
IN schemaName varchar(128) -- If null use name of current schema;
, IN tableName varchar(128) -- If null an exception will be thrown.
, IN indexName varchar(128) -- If null an exception will be thrown.
, IN indexDefinition varchar(1024) -- E.g. '(expireTS_ ASC)'
, IN ifPresent ENUM('leaveUnchanged', 'dropAndReplace') -- null=leaveUnchanged.
, OUT outcome tinyint(1) -- 0=unchanged, 1=replaced, 4=added.
)
BEGIN
DECLARE doDrop tinyint(1) DEFAULT NULL;
DECLARE doAdd tinyint(1) DEFAULT NULL;
DECLARE tmpSql varchar(4096) DEFAULT '';
SET schemaName = coalesce(schemaName, schema());
SET ifPresent = coalesce(ifPresent, 'leaveUnchanged');
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema = schemaName AND table_name = tableName AND index_name = indexName) THEN
IF (ifPresent = 'leaveUnchanged') THEN
SET doDrop = 0;
SET doAdd = 0;
SET outcome = 0;
ELSEIF (ifPresent = 'dropAndReplace')
THEN
SET doDrop = 1;
SET doAdd = 1;
SET outcome = 1;
END IF;
ELSE
SET doDrop = 0;
SET doAdd = 1;
SET outcome = 4;
END IF;
IF (doDrop = 1) THEN
SET tmpSql = concat( 'alter table `', schemaName, '`.`', tableName, '` drop index `', indexName, '` ');
SET @sql = tmpSql;
PREPARE tmp_stmt FROM @sql;
EXECUTE tmp_stmt;
DEALLOCATE PREPARE tmp_stmt;
END IF;
IF (doAdd = 1) THEN
SET tmpSql = concat( 'alter table `', schemaName, '`.`', tableName, '` add index `', indexName, '` (', indexDefinition, ')');
SET @sql = tmpSql;
PREPARE tmp_stmt FROM @sql;
EXECUTE tmp_stmt;
DEALLOCATE PREPARE tmp_stmt;
END IF;
END;
//
DELIMITER ;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With