¿Una clave externa crea automáticamente un índice?

390

Me han dicho que si formo una clave externa en dos tablas, ese SQL Server creará algo similar a un índice en la tabla secundaria. Me cuesta creer que esto sea cierto, pero no puedo encontrar muchas cosas relacionadas específicamente con esto.

Mi verdadera razón para preguntar esto es porque estamos experimentando un tiempo de respuesta muy lento en una declaración de eliminación en una tabla que probablemente tenga 15 tablas relacionadas. Le pregunté a nuestro tipo de base de datos y él dice que si hay una clave externa en los campos, entonces actúa como un índice. ¿Cuál es tu experiencia con esto? ¿Debo agregar índices en todos los campos de clave externa o son solo gastos generales innecesarios?

Nick DeVore
fuente
Tengo el mismo entendimiento que su tipo DB: que los FK de hecho crean un índice.
Vinnie
99
No, un FK NO crea automáticamente un índice. Tiene sentido crear uno, pero SQL Server NO lo hace automáticamente.
marc_s
47
no es tonto preguntar esto en absoluto!
marc_s
55
Si obtiene eliminaciones lentas y la tabla a la que está eliminando hace referencia en otras tablas, probablemente obtendrá un aumento de rendimiento al indexar las claves foráneas en las otras tablas. Esto se debe a que cuando SQL está eliminando una fila, necesita verificar la integridad referencial en la fila. Para hacer esto, obviamente debe verificar que no existan otras filas que hagan referencia a la fila que está eliminando.
Noel Kennedy
3
Yo diría que un tipo de base de datos que no sabía esto debe tener una gran necesidad de capacitación. Las personas de la base de datos son responsables del rendimiento, es su trabajo saber este tipo de cosas. Esto sugiere una incompetencia grave.
HLGEM

Respuestas:

343

Una clave foránea es una restricción, una relación entre dos tablas, que no tiene nada que ver con un índice per se.

Pero es un hecho conocido que tiene mucho sentido indexar todas las columnas que forman parte de cualquier relación de clave externa, porque a través de una relación FK, a menudo necesitará buscar una tabla relacionada y extraer ciertas filas en función de un solo valor o un rango de valores.

Por lo tanto, tiene sentido indexar las columnas involucradas en un FK, pero un FK per se no es un índice.

Consulte el excelente artículo de Kimberly Tripp "¿Cuándo dejó SQL Server de poner índices en columnas de clave externa?" .

marc_s
fuente
Sí. Estoy casi seguro de que PostgreSQL crea un índice. Estoy bastante seguro de que MySQL lo hace. Hacer el índice tiene mucho sentido, pero NO ES NECESARIO. Después de todo, ¿por qué hacer referencia a algo si cada vez que el DB va a buscarlo tiene que hacer un escaneo de tabla?
MBCook
Este artículo mencionado anteriormente es un poco confuso porque el servidor SQL o cualquier otra base de datos nunca pone un índice en FK.
vsingh
77
@vsingh: eso es exactamente lo que el artículo trata de transmitir: es un error común pensar que un FK crea automáticamente un índice, no lo hace.
marc_s
55
@MBCook No, PostgreSQL no (al menos en 9.2 o cualquier versión anterior) crea automáticamente un índice en el lado de referencia de una relación de clave externa definida con REFERENCES. Crea automáticamente un UNIQUEíndice para una restricción PRIMARY KEYo UNIQUE, y requiere que UNIQUEesté presente un índice para el extremo referenciado de una relación de clave externa, pero no hace nada automáticamente para el final de referencia , aunque a menudo es una buena idea hacer uno usted mismo. Ver stackoverflow.com/questions/970562/…
Craig Ringer el
16
La confusión puede existir porque MySQL InnoDB tanto requiere y crea automáticamente un índice cuando se agrega una clave externa - dev.mysql.com/doc/refman/5.5/en/...
humbads
42

Wow, las respuestas están por todo el mapa. Entonces la documentación dice:

Una restricción FOREIGN KEY es candidata para un índice porque:

  • Los cambios en las restricciones PRIMARY KEY se verifican con restricciones FOREIGN KEY en tablas relacionadas.

  • Las columnas de clave externa a menudo se usan en criterios de combinación cuando los datos de tablas relacionadas se combinan en consultas haciendo coincidir las columnas en la restricción de CLAVE EXTRANJERA de una tabla con las columnas de clave principal o única en la otra tabla. Un índice permite a Microsoft® SQL Server ™ 2000 encontrar rápidamente datos relacionados en la tabla de claves foráneas. Sin embargo, crear este índice no es un requisito. Los datos de dos tablas relacionadas se pueden combinar incluso si no se definen restricciones de PRIMARY KEY o FOREIGN KEY entre las tablas, pero una relación de clave externa entre dos tablas indica que las dos tablas se han optimizado para combinarse en una consulta que utiliza las claves como sus criterios

Por lo tanto, parece bastante claro (aunque la documentación está un poco confusa) que, de hecho, no crea un índice.

Yishai
fuente
55
Exactamente, es un CANDIDATO para un índice, ¡pero no se crea automáticamente como uno! Muy claro en realidad, en mi humilde opinión :-)
marc_s
44
Encontré esta parte confusa: "una relación de clave externa entre dos tablas indica que las dos tablas se han optimizado para combinarse en una consulta que utiliza las claves como criterio". Eso debería decir "... dos tablas deben ser optimizadas ..."
Yishai,
18

No, no hay un índice implícito en los campos de clave externa, de lo contrario, ¿por qué Microsoft diría "Crear un índice en una clave externa a menudo es útil" ? Su colega puede ser confuso el campo de clave externa en la tabla referida con la clave primaria en los que se hace referencia a la mesa - claves primarias no crear un índice implícito.

Michael Borgwardt
fuente
¿Qué es "Un índice implícito"? ¿implica simplemente que hay un árbol ab * sin crearlo?
Stephanie Page
1
@Stephanie Page: Es una expresión que acabo de inventar para que esta respuesta signifique un índice que se crea automáticamente. Si declara una clave primaria, el servidor SQL la crea e indexa automáticamente. Pero no si declara una clave foránea (algunos otros sistemas de base de datos lo hacen).
Michael Borgwardt
7

SQL Server crea automáticamente índices para claves principales, pero no para claves externas. Cree el índice para las claves externas. Probablemente valga la pena los gastos generales.

Paul Sonier
fuente
6

Digamos que tiene una mesa grande llamada pedidos y una mesa pequeña llamada clientes. Hay una clave externa de un pedido a un cliente. Ahora, si elimina un cliente, SQL Server debe verificar que no haya pedidos huérfanos; si los hay, genera un error.

Para verificar si hay pedidos, Sql Server tiene que buscar en la tabla de pedidos grandes. Ahora si hay un índice, la búsqueda será rápida; Si no lo hay, la búsqueda será lenta.

Entonces, en este caso, la eliminación lenta podría explicarse por la ausencia de un índice. Especialmente si SQL Server tendría que buscar 15 tablas grandes sin un índice.

PD: si la clave externa tiene ON DELETE CASCADE, Sql Server todavía tiene que buscar en la tabla de pedidos, pero luego eliminar cualquier pedido que haga referencia al cliente eliminado.

Andomar
fuente
Exactamente - esa es la razón por la que un índice en un FK tiene mucho sentido (la mayoría de las veces)
marc_s
1
La mayor parte del tiempo? Parece que este es el caso de una eliminación de un padre. Si la mayoría de las veces borras de los padres, supongo que es cierto.
Stephanie Page
6

Las claves foráneas no crean índices. Solo las restricciones de clave alternativa (ÚNICA) y las restricciones de clave principal crean índices. Esto es cierto en Oracle y SQL Server.

Sandeep Kanuri
fuente
3

No que yo sepa. Una clave externa solo agrega una restricción de que el valor en la clave secundaria también se represente en algún lugar de la columna primaria. No le dice a la base de datos que la clave secundaria también necesita ser indexada, solo restringida.

Gandalf
fuente
3

Estrictamente hablando, las claves externas no tienen absolutamente nada que ver con los índices, sí. Pero, como señalaron los altavoces que estaban encima de mí, tiene sentido crear uno para acelerar las búsquedas de FK. De hecho, en MySQL, si no especifica un índice en su declaración FK, el motor (InnoDB) lo crea automáticamente.

shylent
fuente
3

En PostgeSql puede verificar los índices usted mismo si presiona \ d tablename

Verá que los índices btree se han creado automáticamente en columnas con clave primaria y restricciones únicas, pero no en columnas con claves foráneas.

Creo que eso responde su pregunta al menos para postgres.

Gregor
fuente
Lo siento, no noté que la pregunta se refiere a MS SQL Server, pero después de haber publicado la respuesta. Probablemente todavía podría ayudar a alguien ...
Gregor
2

Noté que Entity Framework 6.1 apuntado a MSSQL agrega automáticamente índices en claves foráneas.

Luke Puplett
fuente
No creo que sea así si marca manualmente la columna como parte de un índice (por ejemplo, si está creando un índice compuesto sobre varios miembros)
Rowland Shaw
0

InnoDB requiere índices en claves externas y claves referenciadas para que las comprobaciones de claves externas puedan ser rápidas y no requieran un escaneo de tabla. En la tabla de referencia, debe haber un índice donde las columnas de clave externa se enumeran como las primeras columnas en el mismo orden.

Talha F.
fuente