O MySQL indexa colunas de chave estrangeira automaticamente?

261

O MySQL indexa colunas de chave estrangeira automaticamente?

Dónal
fonte

Respostas:

229

Sim, mas apenas em . Atualmente, o Innodb é o único formato de tabela enviado que possui chaves estrangeiras implementadas.

Grant Limberg
fonte
1
Você tem algum motivo para acreditar que o MySQL permitirá chaves estrangeiras em colunas não indexadas para qualquer outro tipo de tabela?
Robert Gamble
Eu realmente não pude responder isso. Você pode procurar os mecanismos de armazenamento Maria e Falcon que serão lançados no MySQL 6.0 e ver se eles suportam chaves estrangeiras em colunas não indexadas.
Grant Limberg
Aparentemente, isso não é verdade. Eu tenho uma tabela grande (1 milhão de registros) e contagem (*) onde fkey =? levaria 15 segundos. Adicionado um índice na coluna fkey, e as coisas ficam menos de um segundo agora.
AbiusX
O mesmo experimento com outra tabela e 10 milhões de registros. Este é o MySQL 5.1 InnoDB. A tabela possui três campos, um é o número inteiro da chave primária e o outro já está indexado. A terceira era uma chave estrangeira para a chave primária de outra tabela. Sem adicionar um índice explícito, as pesquisas levaram vários segundos aqui. Mostrar índice da tabela também não mostrou um índice nela.
AbiusX 01/02
O @AbiusX 5.1 provavelmente é muito antigo, veja a resposta de MrAlexander abaixo.
E2-E4
131

Aparentemente, um índice é criado automaticamente, conforme especificado no link que Robert postou .

O InnoDB requer índices em chaves estrangeiras e chaves referenciadas para que as verificações de chave estrangeira possam ser rápidas e não exigir uma varredura de tabela. Na tabela de referência, deve haver um índice em que as colunas de chave estrangeira sejam listadas como as primeiras colunas na mesma ordem. Esse índice é criado na tabela de referência automaticamente se ele não existir. (Isso contrasta com algumas versões mais antigas, nas quais os índices precisavam ser criados explicitamente ou a criação de restrições de chave estrangeira falharia.) Index_name, se fornecido, é usado como descrito anteriormente.

Restrições InnoDB e FOREIGN KEY

Justin Johnson
fonte
9
+1 muito resposta melhor do que aquele selecionado como fornece a prova de docs
Gaz_Edge
6
O texto citado não parece mais ser incluído nos documentos do MySQL, deixando claro se isso ainda é verdade ou não.
Courtney Miles
7
@ user2045006 você pode consultar doc 5.0 , bem doc 5,6 para o texto exato citado
sactiw
1
Nos documentos atuais, há apenas uma pequena alteração no texto (suponho que o significado seja semelhante):InnoDB permits a foreign key to reference any index column or group of columns. However, in the referenced table, there must be an index where the referenced columns are the first columns in the same order.
Lucas Basquerotto
20

Sim, consulte Restrições InnoDB e FOREIGN KEY .

Robert Gamble
fonte
4
Esta resposta é um ótimo exemplo de por que uma resposta nunca deve consistir apenas em um link para uma possível resposta. Neste momento, a página vinculada não responde à pergunta.
Mike
1
Adicione todas as informações à própria resposta em vez de postar apenas um link
Nico Haase
11

Você não obtém o índice automaticamente se fizer um ALTER TABLE (em vez de CREATE TABLE), pelo menos de acordo com os documentos (o link é para 5.1, mas é o mesmo para 5.5):

[...] Ao adicionar uma restrição de chave estrangeira a uma tabela usando ALTER TABLE, lembre-se de criar os índices necessários primeiro.

Thomas Lundström
fonte
2
Eu também tentei no MySQL 5.6 e MariaDB 10 e ALTER TABLE criaram um índice. É interessante que o mysqlindexcheck tenha relatado esse índice como sendo um "índice redundante". Tentei descartá-lo, mas recebi o seguinte erro: "ERRO 1553 (HY000): não é possível eliminar o índice 'index_name': necessário em uma restrição de chave estrangeira". Portanto, não é possível descartar esse índice e manter a chave estrangeira.
Ciprian Stoica
Você pode revisar sua resposta. O MySQL sempre cria um índice para acelerar as verificações de chave estrangeira, se ainda não existir . Os documentos estão tentando dizer que a criação de índices antes das restrições de chave estrangeira pode acelerar um pouco as coisas. Por exemplo, um índice de chave composto que poderia servir como um índice para as verificações de chave estrangeira poderia ser usado pelo InnoDB em vez de gerar automaticamente um índice redundante.
BMiner 22/01/19
7

Para quem procura cotações de 5.7 documentos :

O MySQL requer índices em chaves estrangeiras e chaves referenciadas para que as verificações de chaves estrangeiras possam ser rápidas e não exigir uma varredura de tabela. Na tabela de referência, deve haver um índice em que as colunas de chave estrangeira sejam listadas como as primeiras colunas na mesma ordem. Esse índice é criado na tabela de referência automaticamente se ele não existir. Esse índice pode ser eliminado silenciosamente mais tarde, se você criar outro índice que possa ser usado para impor a restrição de chave estrangeira. index_name, se fornecido, é usado como descrito anteriormente.

Fahmi
fonte
4

Como afirmado, ele faz para o InnoDB. No começo, achei estranho que muitos outros (em particular o MS SQL e o DB2) não o fizessem. As varreduras do TableSpace são melhores do que as varreduras de índice quando existem muito poucas linhas de tabela - portanto, para a grande maioria dos casos, uma chave estrangeira deseja ser indexada. Então isso me atingiu - isso não significa necessariamente que deve ser um índice independente (uma coluna) - onde está no índice FK automático do MySQL. Portanto, talvez seja por isso que o MS SQL, o DB2 (Oracle não tenho certeza) etc deixem para o DBA; afinal, vários índices em tabelas grandes podem causar problemas de desempenho e espaço.

Wolf5370
fonte
Você menciona um bom argumento sobre índices de chave compostos; no entanto, o MySQL eliminará automaticamente / silenciosamente um índice de chave única gerado automaticamente se um índice de chave composto recém-criado cumprir a obrigação de fazer as verificações de chave estrangeira rapidamente. Para ser sincero, não tenho idéia do por que o MS SQL, o DB2 e outros não fazem isso. Eles têm pouca desculpa. Não consigo pensar em um caso de uso em que um índice gerado automaticamente em chaves estrangeiras seria prejudicial.
BMiner 22/01/19
2

Sim, Innodbforneça isso. Você pode colocar um nome de chave estrangeira após a FOREIGN KEYcláusula ou deixar que o MySQL crie um nome para você. O MySQL cria automaticamente um índice com o foreign_key_namenome.

CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name (columns)
REFERENCES parent_table(columns)
ON DELETE action
ON UPDATE action
Navrattan Yadav
fonte
0

Sim, a chave estrangeira do índice Mysql automaticamente quando você cria uma tabela que possui uma chave estrangeira para outra.

giapnh
fonte
-2

Não é possível obter a chave de índice automaticamente

ALTER TABLE (NAME OF THE TABLE) ADD INDEX (FOREIGN KEY)

Nome da tabela que você criou, por exemplo, fotografias e FOREIGN KEY, por exemplo photograph_id. O código deve ser assim

ALTER TABLE photographs ADD INDEX (photograph_id);
Ali Raza
fonte