¿Necesito crear índices en claves externas en Oracle?

120

Tengo una mesa Ay una mesa B. Atiene una clave externa a la clave principal de Bon B,B_ID .

Por alguna razón (sé que hay razones legítimas) no está usando un índice cuando uno estas dos tablas en la clave.

¿Necesito crear un índice por separado A.B_IDo debería proporcionarlo la existencia de una clave externa?

una mierda
fuente

Respuestas:

137

La restricción de clave externa por sí sola no proporciona el índice en Oracle: se debe (y se debe) crear uno.

DCookie
fuente
11
En algunas bases de datos, la creación de una restricción de clave externa también crea un índice ... es decir, Jet Engine (archivos MSAccess, Firebird y MySQL)
bubi
17
Esta respuesta no tiene sentido sin hacer referencia explícita a una implementación de base de datos en particular. Claro que la pregunta está etiquetada, oraclepero eso no es obvio de inmediato cuando aterrizas aquí desde una búsqueda en Google.
developerbmw
5
Puedo confirmar que PostgreSQL, al menos en el momento de esta publicación, no lo hace automáticamente.
The Dembinski
Misma respuesta para SQL Server (2016, Azure ...), hasta donde yo sé.
Pac0
¿Por qué se debe crear un índice en una clave externa con Oracle? ¿Cuáles son las consecuencias de no hacerlo, por favor?
Đỗ Công Bằng
46

La creación de una clave externa no crea automáticamente un índice en A.B_ID. Por lo tanto, desde la perspectiva del rendimiento de las consultas, generalmente tendría sentido crear un índice separado en A.B_ID.

Si alguna vez elimina filas en B, definitivamente desea que A.B_ID se indexe. De lo contrario, Oracle tendrá que hacer un escaneo completo de la tabla en A cada vez que elimine una fila de B para asegurarse de que no haya registros huérfanos (dependiendo de la versión de Oracle, también puede haber implicaciones de bloqueo adicionales, pero estas disminuyen en versiones más recientes de Oracle).

Justin Cave
fuente
1
¿Qué pasa con las columnas PFK? por ejemplo, si tengo una tabla intermedia para una relación de muchos a muchos, ¿debería crear un índice para las dos columnas PFK de esta tabla?
Clamari
3
@Clamari: si C tiene una clave principal de (A_ID, B_ID), la clave principal se encargaría de poder eliminar de A. Si también desea poder eliminar de B de manera eficiente, querrá un índice activado B_ID.
Justin Cave
25

Solo para obtener más información: Oracle no crea un índice automáticamente (como lo hace para las restricciones únicas) porque (a) no es necesario para hacer cumplir la restricción y (b) en algunos casos no es necesario.

Más de las veces, sin embargo, querrá crear un índice (de hecho, en Oracle Apex hay un informe de "claves externas no indexadas").

Siempre que la aplicación necesite poder eliminar una fila en la tabla principal o actualizar el valor PK (que es más raro), el DML sufrirá si no existe un índice, porque tendrá que bloquear toda la tabla secundaria.

Un caso en el que generalmente elijo no agregar un índice es donde el FK está en una tabla de "datos estáticos" que define el dominio de una columna (por ejemplo, una tabla de códigos de estado), donde las actualizaciones y eliminaciones en la tabla principal nunca se realizan directamente por la aplicación. Sin embargo, si agregar un índice en la columna brinda beneficios para consultas importantes en la aplicación, el índice seguirá siendo una buena idea.

Jeffrey Kemp
fuente
14

SQL Server nunca ha colocado índices en columnas de clave externa automáticamente; consulte la excelente publicación de blog de Kim Tripp sobre los antecedentes y la historia de este mito urbano.

Sin embargo, generalmente es una buena idea indexar las columnas de clave externa, así que sí, recomendaría asegurarse de que cada columna FK esté respaldada por un índice; no necesariamente en esa única columna; tal vez tenga sentido crear un índice en dos o tres columnas con la columna FK como la primera allí. Depende de su escenario y sus datos.

marc_s
fuente
8

Por motivos de rendimiento, debería crearse un índice. Se usa en operaciones de eliminación en la tabla primaria (para verificar que el registro que está eliminando no se usa) y en combinaciones que generalmente involucran una clave externa. Solo algunas tablas (no las creo en registros) podrían ser que no necesiten el índice, pero probablemente, en estos casos, probablemente no necesite la restricción de clave externa también.

PERO

Hay algunas bases de datos que ya crean índices automáticamente en claves externas. Jet Engine (archivos de Microsoft Access) Firebird MySQL

SIN LUGAR A DUDA

SQL Server Oracle

NO

bubi
fuente
3
Gracias por mencionar que FIrebird SQL lo hace automáticamente. Ese es exactamente el punto que estaba buscando.
user424855
1

Al igual que con todo lo relacionado con el rendimiento, depende de muchos factores y no existe una bala plateada, por ejemplo, en un entorno de muy alta actividad, el mantenimiento de un índice puede ser inaceptable.

Lo más destacado aquí parecería ser la selectividad: si los valores en el índice estuvieran muy duplicados, entonces podría ofrecer un mejor rendimiento eliminar el índice (si es posible) y permitir un escaneo de la tabla.

un día cuando
fuente
1

Las restricciones UNIQUE, PRIMARY KEY y FOREIGN KEY generan índices que imponen o "retroceden" la restricción (y a veces se denominan índices de respaldo). Las restricciones PRIMARY KEY generan índices únicos. Las restricciones FOREIGN KEY generan índices no únicos. Las restricciones ÚNICAS generan índices únicos si todas las columnas no aceptan valores NULL y generan índices no exclusivos si una o más columnas admiten valores NULL. Por lo tanto, si una columna o un conjunto de columnas tiene una restricción ÚNICA, CLAVE PRIMARIA o CLAVE EXTRANJERA, no es necesario que cree un índice en esas columnas para el rendimiento.

Chinmai
fuente
Los documentos a los que se vinculó son para Derby, la base de datos Java incorporada, no para Oracle.
Davos