2009-04-01 8 views
6

Tengo una tabla que tiene un índice agrupado en dos columnas: la clave principal de la tabla. Se define como sigue:La mejor manera de cambiar el índice agrupado (PK) en SQL 2005

ALTER TABLE Table ADD CONSTRAINT [PK_Table] PRIMARY KEY CLUSTERED 
(
    [ColA] ASC, 
    [ColB] ASC 
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY] 

I desea eliminar esta PK índice agrupado y añadir un índice agrupado como sigue y añadir una restricción de clave primaria utilizando un índice no agrupado, también se muestra a continuación.

CREATE CLUSTERED INDEX [IX_Clustered] ON [Table] 
(
    [ColC] ASC, 
    [ColA] ASC, 
    [ColD] ASC, 
    [ColE] ASC, 
    [ColF] ASC, 
    [ColG] ASC 
)WITH (PAD_INDEX = ON, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF,  DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, FILLFACTOR = 90, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = OFF) ON [PRIMARY] 

ALTER TABLE Table ADD CONSTRAINT 
    PK_Table PRIMARY KEY NONCLUSTERED 
    (
    ColA, 
    ColB 
) WITH(STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 

que iba a caer sólo el PK índice agrupado, a continuación, añadir el nuevo índice agrupado y luego añadir el índice de clave no agrupado primaria, pero supe que borrar el índice agrupado existente haría que los datos de la tabla a ser reordenado (ver respuesta aquí What happens when I drop a clustered primary key in SQL 2005), que no creo que deba ser necesario. La tabla está golpeando 1 TB, así que realmente quiero evitar cualquier reordenamiento innecesario.

Mi pregunta es, ¿cuál es la mejor manera de pasar de la estructura existente a la estructura deseada?

EDIT: Solo quiero aclararlo. La tabla es de 1TB y desafortunadamente no tengo espacio para crear una tabla temporal. Si hay una manera de hacerlo sin crear una tabla temporal, por favor avíseme.

Respuesta

8

Si la tabla es obteniendo hasta 1 TB de tamaño y probablemente tiene MUCHAS filas en él, recomiendo NO hacer que el índice agrupado sea mucho más gordo.

Antes que nada, abandonar y volver a crear el índice agrupado se mezclará con TODOS sus datos al menos una vez; eso solo llevará años.

En segundo lugar, el gran índice agrupado compuesto que intenta crear aumentará significativamente el tamaño de todos sus índices no agrupados (ya que contienen el valor del índice agrupado completo en cada nodo hoja, para las búsquedas de marcador).

La pregunta es más: ¿por qué estás tratando de hacer esto? ¿No podría agregar otro índice no agrupado con esas columnas para cubrir sus consultas? ¿Por qué tiene que ser este el índice agrupado? No veo ninguna ventaja en eso ...

Para obtener más información sobre la indexación y, especialmente, el debate sobre el índice agrupado, consulte Kimberly Tripp's blog en los índices de SQL Server, ¡muy útil!

Marc

4
  1. Crear una nueva tabla:

    CREATE TABLE newtable (colA INT, colB INT) 
    
    • Insertar todos los valores de la tabla antigua en la nueva tabla:

      INSERT EN newtable SELECT * de la Tabla

    • Deja el viejo tabla:

      tabla DROP TABLE

    • Cambiar el nombre de la nueva tabla de la mesa de edad

      EXEC sp_rename 'newtable', 'mesa'

    • Construir los índices:

      ALTER TABLE Tabla ADD CONSTRAINT PK_Table PRIMARY KEY NO CLASICADA ( ColA, ColB ) CON (STATISTICS_NORECOMPUTE = OFF, OFF = IGNORE_DUP_KEY, ALLOW_ROW_LOCKS = ON, allow_page_locks = ON) ON [PRIMARY]

+0

Esa no es una opción. Tengo una tabla de 1TB en un RAID de 1.5TB. –

+0

SQL Server necesitará espacio tanto para el reordenamiento como para el traslado. Si no tiene espacio, puede usar la opción MOVER A en DROP INDEX para crear su tabla en un almacenamiento temporal, y luego volver a crearla en su RAID. – Quassnoi

+0

Puede transferir filas en trozos, eliminándolos de la fuente sobre la marcha. Sin embargo, ese sería un proceso muy lento. –

11

Esta no es una respuesta completa a su pregunta, pero asegúrese que si tienes otros índices sobre la mesa, los sueltas primero. De lo contrario, SQL Server deberá reconstruirlos todos cuando elimine el índice agrupado y luego volver a generarlos cuando vuelva a agregar un nuevo índice agrupado.Los pasos habituales son:

  1. Retire todos los índices no agrupados
  2. Quitar índice agrupado
  3. Añadir nuevo índice agrupado
  4. añadir de nuevo todos los índices no agrupados
+0

Bueno, ese fue mi plan inicial, pero el segundo paso para eliminar el índice agrupado hace que se muevan todos los datos. Esperaba fusionar los pasos 2 y 3 de alguna manera, para evitar un movimiento innecesario de datos. –

-1

Los índices agrupados en realidad no cambia el orden físico de los datos que se almacenan en la tabla en sí. No ha sido así desde SQL 6.5.

Los datos en las páginas se almacenan en el orden correcto. Las páginas se pueden almacenar en el disco en cualquier orden físico.

+0

¿es cierto? Tenía la impresión de que el orden físico de los datos estaba determinado por la clave del clúster. –

+0

Los datos en las páginas se almacenan en el orden correcto. Las páginas se pueden almacenar en el disco en cualquier orden físico. – mrdenny

+2

Es posible que desee actualizar su respuesta para incluir esta distinción. –

Cuestiones relacionadas