create index-sintaxis-tansact-sql.pdf
TRANSCRIPT
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 1
Referencia de Transact-SQL
CREATE INDEX
Crea un índice de una vista o una tabla dada. Sólo el propietario de la tabla o vista puede crear
índices en esa tabla. El propietario de una tabla o vista puede crear un índice en cualquier
momento, independientemente de que haya datos en la tabla o no. Los índices se pueden crear en
tablas o vistas de otra base de datos especificando un nombre calificado de base de datos.
Sintaxis
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
ON { table | view } ( column [ ASC | DESC ] [ ,...n ] )
[ WITH < index_option > [ ,...n] ]
[ ON filegroup ]
< index_option > :: =
{ PAD_INDEX |
FILLFACTOR = fillfactor |
IGNORE_DUP_KEY |
DROP_EXISTING |
STATISTICS_NORECOMPUTE |
SORT_IN_TEMPDB
}
Argumentos
UNIQUE
Crea un índice único (es decir, que no permite que dos filas tengan el mismo valor de índice) en
una tabla o vista. El índice agrupado de una vista debe ser UNIQUE.
Microsoft® SQL Server™ comprueba si hay valores duplicados cuando se crea el índice (si ya
existen datos) y realiza la comprobación cada vez que se agregan datos con una instrucción
INSERT o UPDATE. Si existen valores de clave duplicados, se cancela la instrucción CREATE
INDEX y se devuelve un mensaje de error con el primer duplicado. Varios valores NULL se
consideran como duplicados al crear un índice UNIQUE.
Cuando existe un índice único, las instrucciones UPDATE o INSERT que generen valores de
clave duplicada se deshacen y SQL Server muestra un mensaje de error. Esto se cumple incluso
si las instrucciones UPDATE o INSERT cambian muchas filas pero crean un único duplicado. Si
se realiza un intento de introducir datos donde existe un índice único y se ha especificado la
cláusula IGNORE_DUP_KEY, sólo causarán un error las filas que infrinjan el índice UNIQUE.
Cuando se procesa una instrucción UPDATE, IGNORE_DUP_KEY no tiene efecto.
Modelo Relacional - MSSQL Server
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 2
SQL Server no permite la creación de un índice único sobre columnas que ya contengan valores
duplicados, ya esté establecido o no IGNORE_DUP_KEY. Si se intenta, SQL Server muestra un
mensaje de error; los duplicados deben eliminarse antes de que se pueda crear un índice único
sobre la columna o columnas.
CLUSTERED
Crea un objeto en el que el orden físico de las filas es el mismo que el orden indizado de las filas
y el nivel inferior (hojas) del índice agrupado contiene las filas de datos reales. Una tabla o vista
permite un índice agrupado al mismo tiempo.
Una vista con un índice agrupado se denomina vista indizada. Es necesario crear un índice
agrupado único en una vista antes de poder definir otros índices en la misma vista.
Cree el índice agrupado antes de crear los índices no agrupados. Los índices no agrupados
existentes en las tablas se vuelven a generar al crear un índice agrupado.
Si no se especifica CLUSTERED, se crea un índice no agrupado.
Nota Debido a que el nivel hoja de un índice agrupado y sus páginas de datos son, por
definición, lo mismo, la creación de un índice agrupado y la utilización de la cláusula ON
filegroup mueven efectivamente una tabla desde el archivo en que se creó la tabla al nuevo grupo
de archivos. Antes de crear tablas o índices en grupos de archivos específicos, compruebe qué
grupos de archivos están disponibles y que esos grupos de archivos tengan suficiente espacio
libre para el índice. Es importante que el grupo de archivos tenga al menos 1,2 veces el espacio
requerido para la tabla completa.
NONCLUSTERED
Crea un objeto que especifica la ordenación lógica de una tabla. Con un índice no agrupado, el
orden físico de las filas es independiente del orden indizado. El nivel hoja de un índice no
agrupado contiene las filas del índice. Cada fila del índice contiene el valor de clave no
agrupada, y uno o varios localizadores de fila que apuntan a la fila que contiene dicho valor. Si la
tabla no tiene un índice agrupado, el localizador de fila es la dirección de disco de la fila. Si la
tabla tiene un índice agrupado, el localizador de fila es la clave del índice agrupado de la fila.
Cada tabla puede tener hasta 249 índices no agrupados (sin importar cómo se hayan creado:
implícitamente con las restricciones PRIMARY KEY y UNIQUE, o explícitamente con
CREATE INDEX). Cada índice puede proporcionar acceso a los datos en un orden distinto.
Para las vistas indizadas, sólo se pueden crear índices no agrupados en una vista que ya tenga
definido un índice agrupado. Por lo tanto, el localizador de fila de un índice no agrupado de una
vista indizada siempre es la clave agrupada de la fila.
index_name
Es el nombre del índice. Los nombres de índice deben ser únicos en una tabla o vista, pero no es
necesario que sean únicos en una base de datos. Los nombres de índice deben seguir las reglas de
los identificadores.
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 3
table
Es la tabla que contiene la columna o columnas que deben indizarse. Especificar los nombres de
la base de datos y del propietario de la tabla es opcional.
view
Es el nombre de la vista que se va a indizar. La vista debe definirse con SCHEMABINDING
para crear un índice en ella. La definición de la vista también debe ser determinista. Una vista es
determinista si todas las expresiones de la lista de selección y las cláusulas WHERE y GROUP
BY son deterministas. Además, todas las columnas de claves deben ser precisas. Sólo las
columnas de la vista que no son de clave pueden contener expresiones flotantes (expresiones que
utilizan el tipo de datos float) y las expresiones float no se pueden utilizar en ninguna otra parte
de la definición de la vista.
Para buscar una columna determinista en la vista, utilice la función COLUMNPROPERTY
(propiedad IsDeterministic). La propiedad IsPrecise de la función puede utilizarse para
determinar si las columnas de clave son precisas.
Es necesario crear un índice agrupado único en una vista antes de crear los índices no agrupados.
El optimizador de consultas puede utilizar las vistas indizadas en SQL Server Enterprise o
Developer para acelerar la ejecución de las consultas. No es necesario hacer referencia a la vista
en la consulta para que el optimizador tengan en cuenta esa vista a la hora de hacer una
sustitución.
Al crear vistas indizadas o manipular filas de tablas que participan en una vista indizada, se debe
asignar un valor específico a siete opciones SET. El valor de las opciones SET siguientes debe
ser ON: ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER,
ANSI_NULLS, ANSI_PADDING y ANSI_WARNING. La opción SET
NUMERIC_ROUNDABORT debe ser OFF.
Si alguno de estos valores es diferente, se producirá un error en las instrucciones de modificación
de datos (INSERT, UPDATE, DELETE) que se ejecuten en cualquier tabla a la que haga
referencia una vista indizada, y SQL Server mostrará un mensaje de error con todas las opciones
SET que infringen los requisitos de configuración. Además, para una instrucción SELECT que
implica una vista indizada, si los valores de alguna de las opciones SET no son los requeridos,
SQL Server procesará SELECT sin considerar la sustitución de la vista indizada. Esto asegura
que el resultado de la consulta es correcto, en los casos en que puede verse afectado por las
opciones SET anteriores.
Si la aplicación utiliza una conexión de DB-Library, es necesario asignar el valor requerido a las
siete opciones SET en el servidor. (De forma predeterminada, las conexiones OLE DB y ODBC
han establecido todas las opciones SET correctamente, excepto ARITHABORT.)
Si todas las opciones SET enumeradas no tienen el valor requerido, se podría producir un error al
ejecutar la actualización de algunas operaciones, como BCP, la duplicación o consultas
distribuidas, en tablas que forman parte de las vistas indizadas. En la mayor parte de los casos,
este problema se puede evitar estableciendo ARITHABORT como ON (mediante user options en
la opción de configuración del servidor).
Se recomienda que la opción de usuario ARITHABORT se establezca en todo el servidor como
ON nada más crearse la primera vista indizada o índice de columna calculada en cualquier base
de datos del servidor.
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 4
column
Es la columna o columnas a las que se aplica el índice. Especifique dos o más nombres de
columna para crear un índice compuesto sobre los valores combinados de las columnas
especificadas. Enumere las columnas que desee incluir en el índice compuesto (en orden de
prioridad) entre paréntesis después de table.
Nota No se pueden especificar como columnas de un índice las columnas que contienen tipos de
datos ntext, text o image. Además, una vista no puede incluir columnas text, ntext o image,
aunque no se haga referencia a ellas en la instrucción CREATE INDEX.
Los índices compuestos se utilizan cuando dos o más columnas se buscan mejor como una
unidad o si muchas consultas hacen referencia sólo a columnas del índice. En un único índice
compuesto se pueden combinar hasta 16 columnas. Todas las columnas de un índice compuesto
deben encontrarse en la misma tabla. El tamaño máximo permitido de los valores de índice
combinado es 900 bytes. Es decir, la suma de las longitudes de las columnas de tamaño fijo que
forman el índice compuesto no puede sobrepasar 900 bytes.
[ASC | DESC]
Determina la dirección ascendente o descendente del orden de la columna de índice determinada.
El valor predeterminado es ASC.
n
Es un marcador de posición que indica que se pueden especificar múltiples columnas (columnas)
para cualquier índice particular.
PAD_INDEX
Especifica el espacio que debe dejarse abierto en cada página (nodo) de los niveles intermedios
del índice. La opción PAD_INDEX sólo es útil cuando se especifica también FILLFACTOR,
porque PAD_INDEX utiliza el mismo porcentaje especificado por FILLFACTOR. De forma
predeterminada, SQL Server asegura que cada página de índice contiene suficiente espacio libre
para acomodar al menos una fila del tamaño máximo que pueda tener el índice, dado el conjunto
de claves de las páginas intermedias. Si el porcentaje especificado para FILLFACTOR no es
suficientemente grande para acomodar una fila, SQL Server anula internamente el porcentaje
para permitir el valor mínimo.
Nota El número de filas de una página intermedia de índice no es nunca inferior a dos,
independientemente de lo bajo que sea el valor de FILLFACTOR.
FILLFACTOR = fillfactor
Especifica un porcentaje que indica cuánto debe llenar SQL Server el nivel hoja de cada página
de índices durante la creación de los mismos. Cuando se llena una página de índices, SQL Server
requiere tiempo para dividir la página de índices y hacer sitio a las nuevas filas, lo que resulta
bastante costoso. En el caso de las tablas con muchas actualizaciones, la elección adecuada de un
valor para FILLFACTOR proporciona mejor rendimiento en las actualizaciones que un valor de
FILLFACTOR inadecuado. El valor de FILLFACTOR original se almacena con el índice en
sysindexes.
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 5
Cuando se especifica FILLFACTOR, SQL Server redondea el número de filas que debe
colocarse en cada página. Por ejemplo, emitir CREATE CLUSTERED INDEX ...
FILLFACTOR = 33 crea un índice agrupado con un valor FILLFACTOR del 33 por ciento.
Suponga que SQL Server calcula que 5,2 filas es el 33 por ciento del espacio de una página. SQL
Server redondea esa cantidad, de forma que coloca seis filas en cada página.
Nota La utilización de un valor FILLFACTOR explícito sólo se aplica cuando se crea el índice
por primera vez. SQL Server no mantiene dinámicamente el porcentaje especificado de espacio
libre de página.
Los valores de FILLFACTOR especificados por el usuario pueden estar entre 1 y 100. Si no se
especifica un valor, el valor predeterminado es 0. Cuando FILLFACTOR es 0, sólo se llenan las
páginas de hoja. Para cambiar el valor predeterminado de FILLFACTOR, ejecute sp_configure.
Utilice un valor FILLFACTOR de 100 sólo cuando no se produzcan instrucciones INSERT o
UPDATE, por ejemplo, en el caso de las tablas de sólo lectura. Si FILLFACTOR es 100, SQL
Server crea índices con páginas de hoja 100 por cien llenas. Una instrucción INSERT o
UPDATE ejecutada después de la creación de un índice con un valor de FILLFACTOR del 100
por cien hace que la página se divida con cada INSERT y, posiblemente, con cada UPDATE.
Los valores de FILLFACTOR más pequeños, excepto 0, hacen que SQL Server cree nuevos
índices con páginas hoja que no están completamente llenas. Por ejemplo, un valor de
FILLFACTOR de 10 puede ser una opción razonable al crear un índice en una tabla que se sabe
que contiene una pequeña parte de los datos que posiblemente contendrá en el futuro. Valores
más pequeños de FILLFACTOR hacen también que cada índice requiera más espacio de
almacenamiento.
La siguiente tabla ilustra cómo se llenan las páginas de un índice si se especifica FILLFACTOR.
FILLFACTOR Página intermedia Página hoja
0 por cien Una entrada libre 100 por cien llena
1 a 99 por ciento Una entrada libre <= porcentaje de FILLFACTOR llena
100 por cien Una entrada libre 100 por cien llena
Una entrada libre es el espacio de la página que puede acomodar otra entrada de índice.
Importante La creación de un índice agrupado con un valor de FILLFACTOR afecta a la
cantidad de espacio de almacenamiento que ocupan los datos, porque SQL Server vuelve a
distribuir los datos cuando crea el índice agrupado.
IGNORE_DUP_KEY
Controla qué ocurre cuando se realiza un intento de insertar un valor de clave duplicada en una
columna que sea parte de un índice agrupado único. Si se especificó IGNORE_DUP_KEY para
el índice y se ejecuta una instrucción INSERT que crea una clave duplicada, SQL Server emite
un mensaje de advertencia y no tiene en cuenta la fila duplicada.
Si no se especificó IGNORE_DUP_KEY para el índice, SQL Server emite un mensaje de error y
deshace la instrucción INSERT completa.
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 6
La tabla siguiente muestra cuándo puede utilizarse IGNORE_DUP_KEY.
Tipo de índice Opciones
Agrupado No permitido.
Agrupado único IGNORE_DUP_KEY permitido.
No agrupado No permitido.
No agrupado único IGNORE_DUP_KEY permitido.
DROP_EXISTING
Especifica que el índice agrupado o no agrupado preexistente mencionado debe quitarse y
volverse a generar. El nombre del índice especificado debe ser el mismo que el índice existente
actualmente. Debido a que los índices no agrupados contienen las claves de agrupamiento, los
índices no agrupados deben volverse a generar cuando se quita un índice agrupado. Si se vuelve
a crear un índice agrupado, los índices no agrupados deben volverse a crear para que tengan en
cuenta el nuevo conjunto de claves.
La cláusula DROP_EXISTING mejora el rendimiento cuando se vuelve a crear un índice
agrupado (con el mismo conjunto de claves o con uno distinto) en una tabla que también tiene
índices no agrupados. La cláusula DROP_EXISTING reemplaza la ejecución de una instrucción
DROP INDEX en el antiguo índice agrupado seguida de la ejecución de una instrucción
CREATE INDEX para el nuevo índice agrupado. Los índices no agrupados vuelven a generarse
una vez, sólo si las claves son distintas.
Si las claves no cambian (se proporcionan los mismos nombres de índice y columnas que el
índice original), la cláusula DROP_EXISTING no ordena de nuevo los datos. Esto puede ser útil
si el índice debe compactarse.
Un índice agrupado no se puede convertir en un índice no agrupado mediante la cláusula
DROP_EXISTING; no obstante, un índice agrupado único se puede cambiar a un índice no
único y viceversa.
Nota Al ejecutar una instrucción CREATE INDEX con la cláusula DROP_EXISTING, SQL
Server asume que el índice es coherente, es decir, que no está dañado. Las filas del índice
especificado deben ordenarse por la clave especificada a la que se hace referencia en la
instrucción CREATE INDEX.
STATISTICS_NORECOMPUTE
Especifica que las estadísticas de índices no actualizadas no se vuelven a calcular
automáticamente. Para restaurar la actualización automática de estadísticas, ejecute UPDATE
STATISTICS sin la cláusula NORECOMPUTE.
Importante Deshabilitar el cálculo automático de estadísticas de distribución puede impedir que
el optimizador de consultas de SQL Server elija los planes de ejecución óptimos de las consultas
relativas a la tabla.
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 7
SORT_IN_TEMPDB
Especifica que los resultados de orden intermedios utilizados para crear el índice se almacenarán
en la base de datos tempdb. Esta opción puede reducir el tiempo necesario para crear un índice si
tempdb está en un conjunto de discos diferente que la base de datos del usuario, pero aumenta la
cantidad de espacio en disco utilizado durante la creación del índice.
ON filegroup
Crea el índice especificado en el grupo de archivos (filegroup) dado. El grupo de archivos se
debe haber creado ya al ejecutar CREATE DATABASE o ALTER DATABASE.
Observaciones El espacio se asigna a las tablas e índices en incrementos de una extensión (ocho páginas de 8
kilobytes) a la vez. Cada vez que se llena una extensión, se asigna otra. Los índices de tablas
vacías o muy pequeñas utilizarán asignaciones de páginas individuales hasta que se hayan
agregado 8 páginas al índice y, después, cambiarán a las asignaciones extendidas. Para obtener
un informe acerca del espacio asignado y el utilizado por un índice, utilice sp_spaceused.
La creación de un índice agrupado requiere disponer en la base de datos de un espacio igual
aproximadamente a 1,2 veces el tamaño de los datos. Este espacio es adicional al espacio
empleado por la tabla existente; los datos se duplican para crear el índice agrupado y los datos
antiguos no indizados se eliminan cuando se completa el índice. Al utilizar la instrucción
DROP_EXISTING, el espacio que necesita el índice agrupado es una cantidad igual a los
requisitos de espacio del índice existente. La cantidad de espacio adicional requerido también se
puede ver afectado por el argumento FILLFACTOR especificado.
Al crear un índice en SQL Server 2000, puede utilizar la opción SORT_IN_TEMPDB para
indicar al motor de base de datos que almacene los resultados intermedios de orden del índice en
tempdb. Esta opción puede reducir el tiempo necesario para crear un índice si tempdb está en un
conjunto de discos diferente que la base de datos del usuario, pero aumenta la cantidad de
espacio en disco utilizado para crear un índice. Además del espacio necesario en la base de datos
del usuario para crear el índice, tempdb debe tener la misma cantidad de espacio adicional para
almacenar los resultados intermedios de ordenación.
La instrucción CREATE INDEX se optimiza como cualquier otra consulta. El procesador de
consultas de SQL Server puede elegir explorar otro índice en lugar de explorar una tabla para
guardar en operaciones de E/S. El orden se puede eliminar en algunos casos.
En equipos multiprocesador con SQL Server Enterprise y Developer, CREATE INDEX utiliza
automáticamente más procesadores para explorar y ordenar, igual que hacen otras consultas. El
número de procesadores utilizados para ejecutar una sola instrucción CREATE INDEX viene
determinado por la opción de configuración max degree of parallelism y por la carga de trabajo
actual. Si SQL Server detecta que el sistema está ocupado, el grado de paralelismo de la
operación CREATE INDEX se reduce automáticamente antes de comenzar la ejecución de la
instrucción.
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 8
La copia de seguridad de los grupos de archivos completos afectados por una instrucción
CREATE INDEX desde la última copia de seguridad del grupo de archivos, debe realizarse
como una unidad. Para obtener más información acerca de las copias de seguridad de archivos y
grupos de archivos, consulte BACKUP.
Las operaciones de copia de seguridad y CREATE INDEX no se bloquean entre sí. Si hay una
copia de seguridad en curso, el índice se crea en modo de registro completo, lo que puede
requerir más espacio para registro.
Para mostrar un informe de los índices de un objeto, ejecute sp_helpindex.
Los índices se pueden crear en una tabla temporal. Cuando se quita la tabla o se termina la
sesión, se quitan todos los índices y desencadenadores.
Columnas de tipo variable en índices
El tamaño máximo permitido para una clave de índice es 900 bytes, pero SQL Server 2000
permite crear índices en columnas con un tipo de variable mayor con un tamaño mayor que 900
bytes.
Durante la creación del índice, SQL Server comprueba las siguientes condiciones:
• La suma de todas las columnas de datos fijos que participan en la definición del índice
debe ser menor o igual que 900 bytes. Cuando el índice a crear se compone únicamente de
columnas de datos fijos, el tamaño total de las columnas debe ser menor o igual que 900 bytes.
En caso contrario, no se creará el índice y SQL Server devolverá un error.
• Si la definición del índice está compuesta por columnas de tipo fijo y variable, y las
columnas de datos fijos cumplen la condición anterior (menor o igual que 900 bytes), SQL
Server comprueba el tamaño total de las columnas de tipo variable. Si el tamaño máximo de las
columnas de tipo variable más el tamaño de las columnas de datos fijos es mayor que 900 bytes,
SQL Server crea el índice pero muestra una advertencia al usuario.
La advertencia indica al usuario que si las acciones de inserción o actualización posteriores que
se realicen en las columnas de tipo variable producen, como resultado, un tamaño total mayor
que 900 bytes, no se podrá realizar la acción y se producirá un error en tiempo de ejecución. Del
mismo modo, si la definición del índice está compuesta sólo de columnas de tipo variable y el
tamaño total máximo de estas columnas es mayor que 900 bytes, SQL Server creará el índice
pero devolverá una advertencia.
UNIQUE o PRIMARY KEY pueden contener una columna calculada siempre que cumpla todas
las condiciones de creación del índice. Concretamente, la columna calculada debe ser
determinista, precisa y no debe contener columnas text, ntext o image. Para obtener más
información acerca del determinismo, consulte Funciones deterministas y no deterministas.
La creación de un índice en una vista o columna calculada puede producir un error en una
operación INSERT o UPDATE que antes funcionaba. Este error podría ocurrir cuando la
columna calculada produce un error aritmético.
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 9
Por ejemplo, aunque la columna calculada c del siguiente ejemplo produzca un error aritmético,
la instrucción INSERT funcionará:
CREATE TABLE t1 (a int, b int, c AS a/b)
GO
INSERT INTO t1 VALUES ('1', '0')
GO
En cambio, si después de crear la tabla crea un índice en la columna calculada c, la misma
instrucción INSERT producirá un error.
CREATE TABLE t1 (a int, b int, c AS a/b)
GO
CREATE UNIQUE CLUSTERED INDEX Idx1 ON t1.c
GO
INSERT INTO t1 VALUES ('1', '0')
GO
El resultado de una consulta que utiliza un índice de una vista definido con expresiones
numéricas o float podría diferir de una consulta similar que no utiliza el índice de la vista. Esta
diferencia se podría deber a errores de redondeo durante las acciones INSERT, DELETE o
UPDATE en las tablas subyacentes.
Para evitar que SQL Server utilice vistas indizadas, incluya la sugerencia OPTION (EXPAND
VIEWS) en la consulta. Además, si alguna de las opciones enumeradas no tiene el valor correcto,
el optimizador no utilizará los índices de las vistas. Para obtener más información acerca de la
sugerencia OPTION (EXPAND VIEWS), consulte SELECT.
Restricciones de las vistas indizadas La instrucción SELECT que define una vista indizada no debe tener las palabras clave TOP,
DISTINCT, COMPUTE, HAVING y UNION. No puede tener una subconsulta.
La lista SELECT no puede contener asteriscos (*), listas creadas con el comodín 'table.*',
DISTINCT, COUNT(*), COUNT(<expression>), columnas calculadas de las tablas base y
agregados escalares.
Las listas SELECT sin agregados no pueden tener expresiones. Las lista agregada SELECT
(consultas que contienen GROUP BY) puede incluir SUM y COUNT_BIG(<expression>); debe
contener COUNT_BIG(*). No se permiten otras funciones agregadas, como MIN, MAX,
STDEV, ...
La agregación compleja mediante AVG no puede participar en la lista SELECT de la vista
indizada. No obstante, si una consulta utiliza esta agregación, el optimizador puede utilizar esta
vista indizada para sustituir AVG por una combinación de agregados SUM y COUNT_BIG
simples.
Una columna procedente de una expresión cuyo resultado es un tipo de datos float o que utiliza
expresiones float para su evaluación no puede ser clave de un índice en una vista indizada o en
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 10
una columna calculada de una tabla. Estas columnas se denominan no precisas. Utilice la función
COLUMNPROPERTY para determinar si una columna calculada en particular o una columna de
una vista es precisa.
Las vistas indizadas están sujetas a estas restricciones adicionales:
• El creador del índice debe ser propietario de las tablas. Todas las tablas, la vista y el
índice se deben crear en la misma base de datos.
• La instrucción SELECT que define la vista indizada no puede contener vistas, funciones
de conjunto de filas, funciones en línea ni tablas derivadas. La misma tabla física sólo puede
ocurrir una vez en la instrucción.
• No se permiten operaciones OUTER JOIN en tablas combinadas.
• No se permiten subconsultas ni predicados CONTAINS o FREETEXT en la condición de
búsqueda.
• Si la definición de la vista contiene una cláusula GROUP BY, todas las columnas de
agrupación así como la expresión COUNT_BIG(*) deben aparecer en la lista SELECT de la
vista. Además, estas columnas deben ser las únicas de la cláusula CREATE UNIQUE
CLUSTERED INDEX.
El cuerpo de la definición de una vista que se puede indizar debe ser determinista y preciso, igual
que los requisitos para los índices de columnas calculadas. Consulte Crear índices en columnas
calculadas.
Permisos
De forma predeterminada, los permisos CREATE INDEX se conceden a la función fija de
servidor sysadmin, a las funciones fijas de base de datos db_ddladmin y db_owner y al
propietario de la tabla, y no son transferibles.
Ejemplos
A. Utilizar un índice sencillo
El ejemplo siguiente crea un índice en la columna au_id de la tabla authors.
SET NOCOUNT OFF
USE pubs
IF EXISTS (SELECT name FROM sysindexes
WHERE name = 'au_id_ind')
DROP INDEX authors.au_id_ind
GO
USE pubs
CREATE INDEX au_id_ind
ON authors (au_id)
GO
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 11
B. Utilizar un índice agrupado único
Este ejemplo crea un índice en la columna employeeID de la tabla emp_pay, que exige que sea
único. Este índice ordena físicamente los datos del disco porque se especifica la cláusula
CLUSTERED.
SET NOCOUNT ON
USE tempDB
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'emp_pay')
DROP TABLE emp_pay
GO
USE tempDB
IF EXISTS (SELECT name FROM sysindexes
WHERE name = 'employeeID_ind')
DROP INDEX emp_pay.employeeID_ind
GO
USE tempDB
GO
CREATE TABLE emp_pay
(
employeeID int NOT NULL,
base_pay money NOT NULL,
commission decimal(2, 2) NOT NULL
)
INSERT emp_pay
VALUES (1, 500, .10)
INSERT emp_pay
VALUES (2, 1000, .05)
INSERT emp_pay
VALUES (3, 800, .07)
INSERT emp_pay
VALUES (5, 1500, .03)
INSERT emp_pay
VALUES (9, 750, .06)
GO
SET NOCOUNT OFF
CREATE UNIQUE CLUSTERED INDEX employeeID_ind
ON emp_pay (employeeID)
GO
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 12
C. Utilizar un índice compuesto sencillo
En este ejemplo se crea un índice en las columnas orderID y employeeID de la tabla order_emp.
SET NOCOUNT ON
USE tempDB
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'order_emp')
DROP TABLE order_emp
GO
USE tempDB
IF EXISTS (SELECT name FROM sysindexes
WHERE name = 'emp_order_ind')
DROP INDEX order_emp.emp_order_ind
GO
USE tempDB
GO
CREATE TABLE order_emp
(
orderID int IDENTITY(1000, 1),
employeeID int NOT NULL,
orderdate datetime NOT NULL DEFAULT GETDATE(),
orderamount money NOT NULL
)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (5, '4/12/98', 315.19)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (5, '5/30/98', 1929.04)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (1, '1/03/98', 2039.82)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (1, '1/22/98', 445.29)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (4, '4/05/98', 689.39)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (7, '3/21/98', 1598.23)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (7, '3/21/98', 445.77)
INSERT order_emp (employeeID, orderdate, orderamount)
VALUES (7, '3/22/98', 2178.98)
GO
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 13
SET NOCOUNT OFF
CREATE INDEX emp_order_ind
ON order_emp (orderID, employeeID)
D. Utilizar la opción FILLFACTOR
Este ejemplo utiliza la cláusula FILLFACTOR establecida en 100. Un valor de FILLFACTOR
de 100 llena cada página completamente y sólo es útil cuando se sabe que los valores de los
índices de una tabla no cambiarán nunca.
SET NOCOUNT OFF
USE tempDB
IF EXISTS (SELECT name FROM sysindexes
WHERE name = 'zip_ind')
DROP INDEX authors.zip_ind
GO
USE tempDB
GO
CREATE NONCLUSTERED INDEX zip_ind
ON authors (zip)
WITH FILLFACTOR = 100
E. Utilizar IGNORE_DUP_KEY
Este ejemplo crea un índice agrupado único en la tabla emp_pay. Si se introduce una clave
duplicada, las instrucciones INSERT y UPDATE se omiten.
SET NOCOUNT ON
USE tempDB
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'emp_pay')
DROP TABLE emp_pay
GO
USE tempDB
IF EXISTS (SELECT name FROM sysindexes
WHERE name = 'employeeID_ind')
DROP INDEX emp_pay.employeeID_ind
GO
USE tempDB
GO
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 14
CREATE TABLE emp_pay
(
employeeID int NOT NULL,
base_pay money NOT NULL,
commission decimal(2, 2) NOT NULL
)
INSERT emp_pay
VALUES (1, 500, .10)
INSERT emp_pay
VALUES (2, 1000, .05)
INSERT emp_pay
VALUES (3, 800, .07)
INSERT emp_pay
VALUES (5, 1500, .03)
INSERT emp_pay
VALUES (9, 750, .06)
GO
SET NOCOUNT OFF
GO
CREATE UNIQUE CLUSTERED INDEX employeeID_ind
ON emp_pay(employeeID)
WITH IGNORE_DUP_KEY
F. Crear un índice con PAD_INDEX
Este ejemplo crea un índice del número de identificación de autor en la tabla authors. Sin la
cláusula PAD_INDEX, SQL Server crea páginas hoja que se encuentran llenas al 10 por ciento,
aunque las páginas situadas encima del nivel de hoja se llenan casi completamente. Con
PAD_INDEX las páginas intermedias también se llenan casi al 10 por ciento.
Nota Al menos dos entradas aparecen en las páginas de índice de los índices agrupados únicos
cuando no se especifica PAD_INDEX.
SET NOCOUNT OFF
USE tempDB
IF EXISTS (SELECT name FROM sysindexes
WHERE name = 'au_id_ind')
DROP INDEX authors.au_id_ind
GO
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 15
USE tempDB
CREATE INDEX au_id_ind
ON authors (au_id)
WITH PAD_INDEX, FILLFACTOR = 10
G. Crear un índice de una vista
Este ejemplo creará una vista y un índice de esa vista. A continuación, se incluyen dos consultas
que utilizan la vista indizada.
USE Northwind
GO
--Set the options to support indexed views.
SET NUMERIC_ROUNDABORT OFF
GO
SET
ANSI_PADDING,ANSI_WARNINGS,CONCAT_NULL_YIELDS_NULL,ARITHABORT,QU
OTED_IDENTIFIER,ANSI_NULLS ON
GO
--Create view.
CREATE VIEW V1
WITH SCHEMABINDING
AS
SELECT SUM(UnitPrice*Quantity*(1.00-Discount)) AS Revenue, OrderDate, ProductID,
COUNT_BIG(*) AS COUNT
FROM dbo.[Order Details] od, dbo.Orders o
WHERE od.OrderID=o.OrderID
GROUP BY OrderDate, ProductID
GO
--Create index on the view.
CREATE UNIQUE CLUSTERED INDEX IV1 ON V1 (OrderDate, ProductID)
GO
--This query will use the above indexed view.
SELECT SUM(UnitPrice*Quantity*(1.00-Discount)) AS Rev, OrderDate, ProductID
FROM dbo.[Order Details] od, dbo.Orders o
WHERE od.OrderID=o.OrderID AND ProductID in (2, 4, 25, 13, 7, 89, 22, 34)
AND OrderDate >= '05/01/1998'
GROUP BY OrderDate, ProductID
ORDER BY Rev DESC
MS-SQL Server – Programación Back End
Mg. Jorge Medi@nero A. Pag. 16
--This query will use the above indexed view.
SELECT OrderDate, SUM(UnitPrice*Quantity*(1.00-Discount)) AS Rev
FROM dbo.[Order Details] od, dbo.Orders o
WHERE od.OrderID=o.OrderID AND DATEPART(mm,OrderDate)= 3
AND DATEPART(yy,OrderDate) = 1998
GROUP BY OrderDate
ORDER BY OrderDate ASC
Véase también
ALTER DATABASE
CREATE DATABASE
CREATE STATISTICS
CREATE TABLE
Diseñar un índice
DROP INDEX
DROP STATISTICS
Índices
INSERT
SET
sp_autostats
sp_createstats
sp_dbcmptlevel
sp_dboption
sp_helpindex
sp_spaceused
sysindexes