14

I want to add an index to a table by using the ALTER syntax, but first check if it already exists on the table, and only add the index if it does not exist.

 ALTER TABLE tableName ADD INDEX IX_Table_XYZ (column1);

Is there any way to do this?

JoelC
  • 3,664
  • 9
  • 33
  • 38
Manish Kumar
  • 595
  • 2
  • 5
  • 20

4 Answers4

25

Try like this:

set @x := (select count(*) from information_schema.statistics where table_name = 'table' and index_name = 'IX_Table_XYZ' and table_schema = database());
set @sql := if( @x > 0, 'select ''Index exists.''', 'Alter Table TableName ADD Index IX_Table_XYZ (column1);');
PREPARE stmt FROM @sql;
EXECUTE stmt;
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • This is the best answer! – Mad Dog Tannen May 15 '15 at 12:21
  • 1
    @RahulTripathi Is it needed to DEALLOCATE the stmt? When does this apply? – Mad Dog Tannen May 15 '15 at 12:31
  • 1
    @KayNelson:- DEALLOCATE is not needed. It is used basically if we are using things like cursor. You can refer this: http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-prepared-statements.html which says: *A prepared statement is specific to the session in which it was created. If you terminate a session without deallocating a previously prepared statement, the server deallocates it a* – Rahul Tripathi May 15 '15 at 12:32
  • @KayNelson:- Glad that I helped you as well! – Rahul Tripathi May 15 '15 at 12:37
  • 2
    This is equivalent to `IF NOT EXISTS` and it's a really bad idea. In the end you may end up with an old/obsolete definition of the index in production. – The Impaler Jun 11 '22 at 19:34
5

You can check if the index (by name of the index) exists by using this syntax

SELECT 1        
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = 'yourschema' AND TABLE_NAME='yourtable' AND
INDEX_NAME='yourindex';

Then you could run it in a Stored Procedure like

IF (SELECT 1        
    FROM INFORMATION_SCHEMA.STATISTICS
    WHERE TABLE_SCHEMA = 'yourschema' AND TABLE_NAME='yourtable' AND
    INDEX_NAME='yourindex') != 1 THEN

Alter Table TableName ADD Index IX_Table_XYZ (column1);

END IF;
Mad Dog Tannen
  • 7,129
  • 5
  • 31
  • 55
4

Based on @KayNelson's answer, for me in MySQL 5.7.16 the correct approach was to use IS NULL instead of !=1 in the IF condition.

So a snippet to conditionally add INDEX to a table is:

IF (SELECT 1        
    FROM `INFORMATION_SCHEMA`.`STATISTICS`
    WHERE `TABLE_SCHEMA` = 'yourschema' 
    AND `TABLE_NAME` = 'yourtable'
    AND `INDEX_NAME` = 'yourindex') IS NULL THEN

    ALTER TABLE `yourtable` ADD INDEX `yourindex` (`column1` ASC);

END IF;
martoncsukas
  • 2,077
  • 20
  • 23
0

Another possibility is to check if SHOW INDEX FROM yourTableName WHERE Key_name = 'yourTableIndexName' returns any rows. If the result set isn't empty, the index exists already.

nhcodes
  • 1,206
  • 8
  • 20