2009-02-03 28 views
118

Supongamos que tengo 2 tablas, productos y categorías de productos. Ambas tablas tienen una relación en CategoryId. Y esta es la consulta.¿La clave externa mejora el rendimiento de las consultas?

SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category 
FROM Products p 
INNER JOIN ProductCategories c ON p.CategoryId = c.CategoryId 
WHERE c.CategoryId = 1; 

Cuando creo el plan de ejecución, la tabla ProductCategories realiza la búsqueda del índice del clúster, lo que es una expectativa. Pero para Table Products, realiza un análisis de índice de clúster, lo que me hace dudar. ¿Por qué FK no ayuda a mejorar el rendimiento de las consultas?

Así que tengo que crear un índice en Products.CategoryId. Cuando vuelvo a crear el plan de ejecución, ambas tablas realizan búsqueda de índice. Y el costo del subárbol estimado se reduce mucho.

Mis preguntas son:

  1. lado FK ayuda en la relación de restricción, ¿tiene cualquier otra utilidad? ¿Mejora el rendimiento de las consultas?

  2. ¿Debo crear un índice en todas las columnas FK (me gustó Products.CategoryId) en todas las tablas?

Respuesta

155

Las llaves foráneas son una herramienta de integridad referencial, no una herramienta de rendimiento. Al menos en SQL Server, la creación de un FK no crea un índice asociado, y debe crear índices en todos los campos FK para mejorar los tiempos de búsqueda.

+9

+1: El modelo es una cosa. El rendimiento es otro. –

+27

Los buenos modelos (generalmente) funcionan mejor. –

+7

"Las claves externas son una herramienta de integridad relacional": utilice la palabra "relacional" con cuidado. Las claves foráneas son un concepto de base de datos, una mano corta para una restricción de integridad referencial. No son parte del modelo relacional. Supongo que cometiste un error tipográfico. – onedaywhen

13

Una clave foránea es un concepto de DBMS para garantizar la integridad de la base de datos.

Cualquier implicancia/mejora de rendimiento será específica de la tecnología de base de datos que se utiliza y es secundaria a la finalidad de una clave externa.

Es una buena práctica en SQL Server asegurarse de que todas las claves externas tengan al menos un índice no agrupado.

Espero que esto aclare las cosas para usted, pero no dude en solicitar más detalles.

+4

El rendimiento es una venta más fácil que la 'integridad de la base de datos'. –

+8

@Kenny Evitt si no tiene integridad, sus datos son inútiles. Me parece que se vende muy fácilmente. – HLGEM

+0

@HLGEM Obtener un [error 404] (http://en.wikipedia.org/wiki/HTTP_404) de vez en cuando es bastante soportable. Tener un rendimiento excepcional a cambio de usar recursos más baratos y sistemas menos complejos, ahora que se vende muy fácilmente también. Puede que le interese el [C.A.P. teorema] (http://en.wikipedia.org/wiki/CAP_theorem). –

47

claves externas pueden mejorar (y el dolor) el rendimiento

  1. Como se ha dicho aquí: Foreign keys boost performance

  2. Siempre debe crear índices en columnas FK para reducir las búsquedas. SQL Server no hace esto automáticamente.

Editar

Como el enlace ahora parece estar muerto (felicitaciones a Chris por notarlo), siguiente muestra la esencia de por qué las claves externas pueden mejorar (y el dolor) el rendimiento.

Can Foreign key improve performance

restricción de clave externa a mejorar el rendimiento en el momento de la lectura de los datos pero al mismo tiempo se ralentiza el rendimiento en el momento de insertar/modificar/borrar datos.

En caso de leer la consulta, el optimizador puede usar restricciones de clave externa a crear planes de consulta más eficientes ya que las restricciones de clave externa son reglas declaradas previamente. Esto generalmente implica omitir alguna parte del plan de consulta porque, por ejemplo, el optimizador puede ver que debido a una restricción de clave externa, no es necesario ejecutar esa parte en particular del plan.

+2

Aquí hay un enlace que detalla las formas en que pueden degradar el rendimiento http://www.devx.com/getHelpOn/10MinuteSolution/16595/0/page/2 – cmsjr

+2

Eso tiene sentido, pero solo se encontrará con esto con una enorme eliminar declaración. Quizás la conclusión debería ser que, en entornos OLAP, las FK no indexadas mejorarían el rendimiento en entornos OLTP, pero degradarían el rendimiento. –

+1

El enlace en esta respuesta está muerto. Esto es desafortunado ya que es el único argumento aquí para que FK mejore el rendimiento. –

3

Puede usarlo para ayudar a hacer una consulta más eficiente. Le permite reestructurar consultas en SQL Server para usar una combinación externa en lugar de una interna que elimina los servidores SQL necesarios para tener que verificar si hay un nulo en la columna. No es necesario que coloque ese calificador porque la relación de clave externa ya lo informa por usted.

Así que esto:

select p.ProductId, p.Name, c.CategoryId, c.Name AS Category 
from Products p inner join ProductCategories c on p.CategoryId = c.CategoryIdwhere c.CategoryId = 1; 

Se convierte en esto:

SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category 
FROM ProductCategories c 
LEFT OUTER JOIN Products P ON 
c.CategoryId = p.CategoryId 
WHERE c.CategoryId = 1; 

Esto no necesariamente hacer una gran actuación en pequeñas consultas, pero cuando consiguen grandes mesas que pueden ser más eficientes.

+3

Las uniones externas normalmente no son menos eficientes que las combinaciones internas (http://stackoverflow.com/a/2726683/155892), ahora sus consultas son engañosas: confía en la base de datos para convertir implícitamente sus uniones externas en uniones internas (restaurar el rendimiento) en lugar de simplemente hacer eso explícitamente –

4

Su mejor apuesta de rendimiento es usar índices en los campos que usa con frecuencia. Si usa SQL Server, puede usar Profiler para crear un perfil de una base de datos específica y tomar el archivo que genera y usar el asistente de ajuste para recibir recomendaciones sobre dónde colocar sus índices. También me gusta usar el generador de perfiles para eliminar los procedimientos almacenados de larga ejecución, tengo una lista de los diez principales delincuentes que publico cada semana, mantiene a la gente honesta: D.

1

No sé mucho sobre SQL Server, pero en el caso de Oracle, tener una columna de clave externa reduce el rendimiento de la carga de datos. Esto se debe a que la base de datos debe verificar la integridad de los datos para cada inserción. Y sí, como ya se mencionó, tener un índice en la columna de clave externa es una buena práctica.

1

Agregar una clave externa en la tabla no mejorará el rendimiento, simplemente diciendo que si está insertando un registro en una tabla de Categorías de productos intentará encontrar que la columna clave externa tiene un valor que existe en el valor de la clave principal de la tabla de productos. esta búsqueda, la operación está sobrecargada en su base de datos cada vez que agrega una nueva entrada en la tabla ProductCategories. Por lo tanto, agregar una clave externa no mejorará el rendimiento de su base de datos, pero se ocupará de la integridad de su base de datos. Sí, mejorará el rendimiento de su BD si está comprobando la integridad utilizando una clave externa en lugar de ejecutar muchas consultas para verificar que el registro exista en la base de datos de su programa.

Cuestiones relacionadas