Como faço para verificar se existe um índice em um campo de tabela no MySQL?


105

Eu precisei pesquisar isso no Google algumas vezes, então estou compartilhando minhas perguntas e respostas.

Respostas:


139

Use SHOW INDEXassim:

SHOW INDEX FROM [tablename]

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


35
MOSTRAR ÍNDICE DE my_tableWHERE Key_name = 'index_to_check';
mit

6
É melhor usar Column_name em vez de Key_name, desta forma você não precisa descobrir o nome do índice se ele for adicionado automaticamente sem nome.
Programista de

Como verificar várias chaves?
berserk de

Tenha cuidado e teste todas as instruções usando isso. Isso falha em algumas tabelas em meu banco de dados ao tentar usá-lo com LiquiBase 1.9.5. Talvez meu banco de dados esteja corrompido. Ou talvez seja um bug na versão antiga do LiquiBase que estou usando no trabalho.
Steve Gelman

36

Experimentar:

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

Ele dirá se existe um índice de qualquer tipo em uma determinada coluna, sem a necessidade de saber o nome dado ao índice. Também funcionará em um procedimento armazenado (ao contrário de mostrar o índice)


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

você pode descobrir se existe uma chave única na tabela


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

4

Use a seguinte instrução: SHOW INDEX FROM your_table

E então verifique o resultado para os campos: linha ["Tabela"], linha ["Nome_chave"]

Certifique-se de escrever "Key_name" corretamente


1

para ver apenas um layout de tabelas do cli. você faria

desc mytable

ou

mostrar mesa minha mesa


0

Se você precisar da funcionalidade se existir um índice para uma coluna (aqui em primeiro lugar na sequência) como uma função de banco de dados, você pode usar / adotar este código. Se você deseja verificar se um índice existe independentemente da posição em um índice de várias colunas, então apenas exclua a 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

você pode usar a seguinte instrução SQL para verificar se a coluna fornecida na tabela foi indexada ou não

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;

uma vez que as junções são contra INNODB_SYS_ *, então os índices de correspondência vieram apenas de tabelas INNODB


-1

Tente usar este:

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

Você não pode executar uma consulta de índice de exibição específica porque ela lançará um erro se um índice não existir. Portanto, você deve pegar todos os índices em uma matriz e percorrê-los se quiser evitar erros de SQL.

Veja como eu faço isso. Eu pego todos os índices da tabela (neste caso leads) e então, em um loop foreach, verifico se o nome da coluna (neste caso, province) existe ou não.

$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;
    }
}

Dessa forma, você pode realmente restringir os atributos do índice. Faça um print_rde $respara ver com o que você pode trabalhar.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.