índice y clave primaria de sql

106

Digamos que tengo una fila de ID (int) en una base de datos establecida como clave principal. Si consulto el ID con frecuencia, ¿también necesito indexarlo? ¿O es una clave principal que ya está indexada?

La razón por la que pregunto es porque en MS SQL Server puedo crear un índice en esta ID, que como dije es mi clave principal.

Editar: una pregunta adicional: ¿hará algún daño indexar adicionalmente la clave principal?

danifo
fuente

Respuestas:

73

Tiene razón, es confuso que SQL Server le permita crear índices duplicados en el mismo campo (s). Pero el hecho de que pueda crear otro no indica que el índice PK tampoco exista.

El índice adicional no sirve de nada, pero el único daño (muy pequeño) es el tamaño de archivo adicional y la sobrecarga de creación de filas.

dkretz
fuente
39
El daño de los índices no utilizados es realmente muy dañino. Por un lado, los índices consumen almacenamiento. Por otro lado, ralentiza las escrituras y las actualizaciones. Elimine siempre los índices que no se utilizarán.
Pacerier
50

Como ya han dicho todos los demás, las claves primarias se indexan automáticamente.

Crear más índices en la columna de clave principal solo tiene sentido cuando necesita optimizar una consulta que utiliza la clave principal y algunas otras columnas específicas. Al crear otro índice en la columna de clave principal e incluir algunas otras columnas con él, puede alcanzar la optimización deseada para una consulta.

Por ejemplo, tiene una tabla con muchas columnas, pero solo está consultando las columnas ID, Nombre y Dirección. Tomando el ID como clave principal, podemos crear el siguiente índice que se basa en el ID, pero incluye las columnas Nombre y Dirección.

CREATE NONCLUSTERED INDEX MyIndex
ON MyTable(ID)
INCLUDE (Name, Address)

Entonces, cuando usa esta consulta:

SELECT ID, Name, Address FROM MyTable WHERE ID > 1000

SQL Server le dará el resultado solo utilizando el índice que ha creado y no leerá nada de la tabla real.

trébol rojo
fuente
28

NOTA: Esta respuesta aborda el desarrollo de clase empresarial en general .

Este es un problema de RDBMS, no solo de SQL Server, y el comportamiento puede ser muy interesante. Por un lado, aunque es común que las claves primarias se indexen automáticamente (de forma única), NO es absoluto. Hay ocasiones en las que es esencial que una clave principal NO se indexe de forma única.

En la mayoría de los RDBMS, se creará automáticamente un índice único en una clave principal si aún no existe uno . Por lo tanto, puede crear su propio índice en la columna de clave principal antes de declararlo como clave principal, luego ese índice será utilizado (si es aceptable) por el motor de base de datos cuando aplique la declaración de clave principal. A menudo, puede crear la clave principal y permitir que se cree su índice único predeterminado, luego crear su propio índice alternativo en esa columna y luego eliminar el índice predeterminado.

Ahora, la parte divertida: ¿cuándo NO desea un índice de clave primaria único? No quiere uno, y no puede tolerarlo, cuando su tabla adquiere suficientes datos (filas) para que el mantenimiento del índice sea demasiado caro. Esto varía según el hardware, el motor RDBMS, las características de la tabla y la base de datos y la carga del sistema. Sin embargo, normalmente comienza a manifestarse una vez que una tabla alcanza algunos millones de filas.

El problema esencial es que cada inserción de una fila o actualización de la columna de clave principal da como resultado un análisis de índice para garantizar la exclusividad. Ese escaneo de índice único (o su equivalente en cualquier RDBMS) se vuelve mucho más costoso a medida que la tabla crece, hasta que domina el rendimiento de la tabla.

Me he ocupado de este problema muchas veces con tablas de hasta dos mil millones de filas, 8 TB de almacenamiento y cuarenta millones de inserciones de filas por día. Se me encomendó la tarea de rediseñar el sistema involucrado, que incluía eliminar el índice de clave primaria única prácticamente como el primer paso. De hecho, era necesario eliminar ese índice en la producción simplemente para recuperarse de una interrupción, incluso antes de acercarnos a un rediseño. Ese rediseño incluyó la búsqueda de otras formas de garantizar la singularidad de la clave principal y proporcionar un acceso rápido a los datos.

Rob Williams
fuente
¿Qué pasa si la clave es una clave de autoincremento int o bigint? ¿Es SQL Server lo suficientemente inteligente como para no realizar un escaneo de índice único en este caso?
Quillbreaker
1
@quillbreaker: IDENTITYno se garantiza que un campo sea único. Después de todo, los usuarios pueden insertar valores duplicados si son usuarios IDENTITY_INSERT.
Sé que este es un tema antiguo, pero no entiendo cómo un escaneo de unicidad de un índice sería una carga para el sistema. Un escaneo de árbol B + debe ser O (log n) * v donde v es una sobrecarga restringida para la fragmentación del índice, el equilibrio imperfecto del árbol, etc. 2 o 3 o incluso 10. 40M de insertos por día son aproximadamente 462 / seg, ~ 100 IO por inserto ... Ahh ... Oh. Veo. Y esto fue antes de los SSD generalizados.
Charles Burns
A menos que elimine la restricción de unicidad, ¿no sería mucho mayor la sobrecarga de verificar cada una de las filas en busca de unicidad?
Max Candocia
20

Las claves primarias siempre están indexadas de forma predeterminada.

Puede definir una clave principal en SQL Server 2012 mediante SQL Server Management Studio o Transact-SQL. La creación de una clave primaria crea automáticamente un índice exclusivo, agrupado o no agrupado correspondiente.

http://technet.microsoft.com/en-us/library/ms189039.aspx

jcollum
fuente
9

Aquí el pasaje del MSDN :

Cuando especifica una restricción PRIMARY KEY para una tabla, el motor de base de datos impone la unicidad de los datos creando un índice único para las columnas de clave principal. Este índice también permite un acceso rápido a los datos cuando se utiliza la clave principal en las consultas. Por lo tanto, las claves primarias que se eligen deben seguir las reglas para crear índices únicos.

MicSim
fuente
8

un PK se convertirá en un índice agrupado a menos que especifique no agrupado

SQLMenace
fuente
3

Declarar una restricción PRIMARY KEYo UNIQUEhace que SQL Server cree automáticamente un índice.

Se puede crear un índice único sin coincidir con una restricción, pero una restricción (ya sea clave principal o única) no puede existir sin tener un índice único.

A partir de aquí, la creación de una restricción:

  • hacer que se cree un índice con el mismo nombre
  • negar la eliminación del índice creado ya que no se permite que exista una restricción sin él

y al mismo tiempo eliminar la restricción eliminará el índice asociado.

Entonces, ¿existe una diferencia real entre a PRIMARY KEYo UNIQUE INDEX:

  • NULLlos valores no están PRIMARY KEYpermitidos en el UNIQUEíndice , pero sí están permitidos ; y al igual que en los operadores de conjuntos (UNION, EXCEPT, INTERSECT), aquí lo NULL = NULLque significa que solo puede tener un valor ya que dos NULLs se encuentran como duplicados entre sí;
  • solo PRIMARY KEYpuede existir uno por tabla, mientras que se pueden crear 999 índices únicos
  • cuando PRIMARY KEYse crea una restricción, se crea como agrupada a menos que ya exista un índice agrupado en la tabla o NONCLUSTEREDse use en su definición; cuando UNIQUEse crea el índice, se crea como a NONCLUSTEREDmenos que no sea específico CLUSTEREDy tal ya no exista;
gotqn
fuente
2

Convertirla en una clave principal también debería crear automáticamente un índice para ella.

EJ Brennan
fuente
1

Bueno, en SQL Server, generalmente, la clave primaria se indexa automáticamente. Esto es cierto, pero no garantiza una consulta más rápida. La clave principal le brindará un rendimiento excelente cuando solo haya un campo como clave principal. Pero, cuando hay varios campos como clave principal, el índice se basa en esos campos.

Por ejemplo: Los campos A, B, C son la clave principal, por lo tanto, cuando realiza una consulta basada en esos 3 campos en su CLAUSULA DONDE, el rendimiento es bueno, PERO cuando desea consultar con el campo Solo C en la CLAUSULA DONDE, no obtendrá un buen rendimiento. Por lo tanto, para poner en marcha su rendimiento, deberá indexar el campo C manualmente.

La mayoría de las veces, no verá el problema hasta que alcance más de 1 millón de registros.

Susanto Siman
fuente
0

Tengo una enorme base de datos sin índice (separado).

Cada vez que consulto por la clave principal, los resultados son, para todos los propósitos intensivos, instantáneos.

Conceder
fuente
Eso se debe a que el PK es un índice agrupado, mire su plan de consulta
SQLMenace
0

las claves primarias se indexan automáticamente

puede crear índices adicionales usando el pk dependiendo de su uso

  • index zip_code, id puede ser útil si a menudo selecciona por zip_code e id
mson
fuente