Come posso verificare se esiste un indice su un campo della tabella in MySQL?


105

Ho dovuto cercarlo su Google un paio di volte, quindi condivido la mia domanda / risposta.

Risposte:


139

Usa SHOW INDEXcosì:

SHOW INDEX FROM [tablename]

Documenti: https://dev.mysql.com/doc/refman/5.0/en/show-index.html


35
MOSTRA INDICE DA my_tableDOVE Key_name = 'index_to_check';
mit

6
Meglio usare Column_name invece di Key_name, in questo modo non è necessario scoprire il nome dell'indice se viene aggiunto automaticamente senza nome.
Programista

Come controllare più chiavi?
berserk

Fai attenzione e prova tutte le affermazioni usando questo. Questo fallisce su alcune tabelle nel mio database quando si tenta di usarlo con LiquiBase 1.9.5. Forse il mio DB è danneggiato. O forse è un bug nell'antica versione di LiquiBase che sto usando al lavoro.
Steve Gelman

36

Provare:

SELECT * FROM information_schema.statistics 
  WHERE table_schema = [DATABASE NAME] 
    AND table_name = [TABLE NAME] AND column_name = [COLUMN NAME]

Ti dirà se c'è un indice di qualsiasi tipo su una certa colonna senza la necessità di conoscere il nome dato all'indice. Funzionerà anche in una procedura memorizzata (al contrario di mostrare indice)


9
SHOW KEYS FROM  tablename WHERE Key_name='unique key name'

puoi scoprire se esiste una chiave univoca nella tabella


8
show index from table_name where Column_name='column_name';

4

Usa la seguente dichiarazione: SHOW INDEX FROM your_table

Quindi controlla il risultato per i campi: riga ["Tabella"], riga ["Key_name"]

Assicurati di scrivere correttamente "Key_name"


1

per guardare solo un layout di tabelle dal cli. faresti

desc mytable

o

mostra tavolo mytable


0

Se hai bisogno della funzionalità se esiste un indice per una colonna (qui al primo posto in sequenza) come funzione di database puoi usare / adottare questo codice. Se vuoi controllare se esiste un indice indipendentemente dalla posizione in un indice a più colonne, elimina la parte "AND SEQ_IN_INDEX = 1".

DELIMITER $$
CREATE FUNCTION `fct_check_if_index_for_column_exists_at_first_place`(
    `IN_SCHEMA` VARCHAR(255),
    `IN_TABLE` VARCHAR(255),
    `IN_COLUMN` VARCHAR(255)
)
RETURNS tinyint(4)
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'Check if index exists at first place in sequence for a given column in a given table in a given schema. Returns -1 if schema does not exist. Returns -2 if table does not exist. Returns -3 if column does not exist. If index exists in first place it returns 1, otherwise 0.'
BEGIN

-- Check if index exists at first place in sequence for a given column in a given table in a given schema. 
-- Returns -1 if schema does not exist. 
-- Returns -2 if table does not exist. 
-- Returns -3 if column does not exist. 
-- If the index exists in first place it returns 1, otherwise 0.
-- Example call: SELECT fct_check_if_index_for_column_exists_at_first_place('schema_name', 'table_name', 'index_name');

-- check if schema exists
SELECT 
    COUNT(*) INTO @COUNT_EXISTS
FROM 
    INFORMATION_SCHEMA.SCHEMATA
WHERE 
    SCHEMA_NAME = IN_SCHEMA
;

IF @COUNT_EXISTS = 0 THEN
    RETURN -1;
END IF;


-- check if table exists
SELECT 
    COUNT(*) INTO @COUNT_EXISTS
FROM 
    INFORMATION_SCHEMA.TABLES
WHERE 
    TABLE_SCHEMA = IN_SCHEMA
AND TABLE_NAME = IN_TABLE
;

IF @COUNT_EXISTS = 0 THEN
    RETURN -2;
END IF;


-- check if column exists
SELECT 
    COUNT(*) INTO @COUNT_EXISTS
FROM 
    INFORMATION_SCHEMA.COLUMNS
WHERE 
    TABLE_SCHEMA = IN_SCHEMA
AND TABLE_NAME = IN_TABLE
AND COLUMN_NAME = IN_COLUMN
;

IF @COUNT_EXISTS = 0 THEN
    RETURN -3;
END IF;

-- check if index exists at first place in sequence
SELECT 
    COUNT(*) INTO @COUNT_EXISTS
FROM 
    information_schema.statistics 
WHERE 
    TABLE_SCHEMA = IN_SCHEMA
AND TABLE_NAME = IN_TABLE AND COLUMN_NAME = IN_COLUMN
AND SEQ_IN_INDEX = 1;


IF @COUNT_EXISTS > 0 THEN
    RETURN 1;
ELSE
    RETURN 0;
END IF;


END$$
DELIMITER ;

-1

è possibile utilizzare la seguente istruzione SQL per verificare che la colonna data sulla tabella sia stata indicizzata o meno

select  a.table_schema, a.table_name, a.column_name, index_name
from    information_schema.columns a
join    information_schema.tables  b on a.table_schema  = b.table_schema and
                                    a.table_name = b.table_name and 
                                    b.table_type = 'BASE TABLE'
left join (
 select     concat(x.name, '/', y.name) full_path_schema, y.name index_name
 FROM   information_schema.INNODB_SYS_TABLES  as x
 JOIN   information_schema.INNODB_SYS_INDEXES as y on x.TABLE_ID = y.TABLE_ID
 WHERE  x.name = 'your_schema'
 and    y.name = 'your_column') d on concat(a.table_schema, '/', a.table_name, '/', a.column_name) = d.full_path_schema
where   a.table_schema = 'your_schema'
and     a.column_name  = 'your_column'
order by a.table_schema, a.table_name;

poiché i join sono contro INNODB_SYS_ *, quindi gli indici di corrispondenza provenivano solo da tabelle INNODB


-1

Prova a usare questo:

SELECT TRUE
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
WHERE TABLE_SCHEMA = "{DB_NAME}" 
AND TABLE_NAME = "{DB_TABLE}"
AND COLUMN_NAME = "{DB_INDEXED_FIELD}";

-3

Non è possibile eseguire una specifica query sull'indice dello spettacolo perché genererà un errore se un indice non esiste. Pertanto, è necessario catturare tutti gli indici in un array e scorrerli se si desidera evitare errori SQL.

Ecco come lo faccio. Prendo tutti gli indici dalla tabella (in questo caso, leads) e poi, in un ciclo foreach, controllo se il nome della colonna (in questo caso, province) esiste o meno.

$this->name = 'province';

$stm = $this->db->prepare('show index from `leads`');
$stm->execute();
$res = $stm->fetchAll();
$index_exists = false;

foreach ($res as $r) {
    if ($r['Column_name'] == $this->name) {
        $index_exists = true;
    }
}

In questo modo puoi davvero restringere gli attributi dell'indice. Fai uno print_rdi $resper vedere con cosa puoi lavorare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.