Professional Documents
Culture Documents
Este tema an no ha recibido ninguna valoracin - Valorar este tema Los ndices mal diseados y la falta de ndices constituyen las principales fuentes de atascos en aplicaciones de base de datos. El diseo eficaz de los ndices tiene gran importancia para conseguir un buen rendimiento de una base de datos y una aplicacin. Esta gua de diseo de ndices de SQL Server contiene informacin y prcticas recomendadas que le ayudarn a disear ndices eficaces que resuelvan las necesidades de la aplicacin.
Se aplica a: SQL Server 2005 a SQL Server 2012, a menos que se especifique lo contrario.
En esta gua se da por supuesto que el lector tiene informacin general sobre los tipos de ndice disponibles en SQL Server. Para obtener una descripcin general de los tipos de ndice, vea Tipos de ndice.
En esta gua
Conceptos bsicos del diseo de ndices Directrices generales para disear ndices Directrices para disear ndices clster Directrices para disear ndices no clster Directrices para disear ndices nicos Directrices generales para disear ndices filtrados Lecturas adicionales
seleccin de ndices al optimizador de consultas y confiar en que tomar la decisin correcta. As se reduce el tiempo de anlisis y se obtiene un buen rendimiento en diversas situaciones. Para saber qu ndices utiliza el optimizador de consultas para determinada consulta, en SQL Server Management Studio, en el men Consulta, seleccione Incluir plan de ejecucin real. No equipare siempre la utilizacin de ndices con un buen rendimiento ni el buen rendimiento al uso eficaz del ndice. Si la utilizacin de un ndice contribuyera siempre a producir el mejor rendimiento, el trabajo del optimizador de consultas sera muy sencillo. En realidad, una eleccin incorrecta de ndice puede provocar un rendimiento bajo. Por tanto, la tarea del optimizador de consultas consiste en seleccionar un ndice o una combinacin de ndices solo si mejora el rendimiento, y evitar la recuperacin indizada cuando afecte al mismo.
mientras se mantiene la integridad de la coleccin global. Para obtener ms informacin, vea Tablas e ndices con particiones. Al considerar la posibilidad de utilizar particiones, determine si el ndice debe alinearse; es decir, si las particiones se crean esencialmente del mismo modo que la tabla o de forma independiente.
La utilizacin de ndices puede mejorar el rendimiento de las consultas, ya que los datos necesarios para satisfacer las necesidades de la consulta existen en el propio ndice. Es decir, solo se requieren las pginas de ndice, y no las pginas de datos de la tabla o el ndice clster, para recuperar los datos solicitados; por lo tanto, se reduce la E/S de disco global. Por ejemplo, una consulta de las columnas a y b en una tabla que tiene un ndice compuesto creado en las columnas a, b y cpuede recuperar los datos especificados del ndice. Escriba consultas que inserten o modifiquen tantas filas como sea posible en una sola instruccin, en lugar de utilizar varias consultas para actualizar las mismas filas.Al utilizar solo una instruccin, se puede aprovechar el mantenimiento de ndices optimizados. Analice el tipo de la consulta y cmo se utilizan las columnas en ella. Por ejemplo, una columna utilizada en una consulta de coincidencia exacta sera una buena candidata para un ndice no clster o clster.
Tenga en cuenta el orden de las columnas si el ndice va a contener varias columnas. La columna que se utiliza en la clusula WHERE en una condicin de bsqueda igual a (=), mayor que (>), menor que (<) o BETWEEN, o que participa en una combinacin, debe situarse en primer lugar. Las dems columnas deben ordenarse basndose en su nivel de diferenciacin, es decir, de ms distintas a menos distintas. Por ejemplo, si el ndice se define como LastName, FirstName, resultar til si el criterio de bsqueda es WHERE LastName = 'Smith' o WHERE LastName = Smith AND FirstName LIKE 'J%'. Sin embargo, el optimizador de consultas no utilizar el ndice en una consulta que solo busque FirstName (WHERE FirstName = 'Jane'). Tenga en cuenta la indizacin de columnas calculadas. Para obtener ms informacin, vea ndices en columnas calculadas.
a todos los discos, ya que todos los datos e ndices estn repartidos por igual entre todos los discos independientemente de la forma de acceso a los datos. Tambin se trata de un mtodo ms sencillo para los administradores de sistemas.
Si se crea un ndice con columnas de clave que coincidan con las de la clusula ORDER BY de la consulta, se puede eliminar el operador SORT del plan de consultas y ste resulta ms eficaz. CREATE NONCLUSTERED INDEX IX_PurchaseOrderDetail_RejectedQty ON Purchasing.PurchaseOrderDetail (RejectedQty DESC, ProductID ASC, DueDate, OrderQty); Cuando se ejecuta de nuevo la consulta, el plan de consultas siguiente muestra que se ha eliminado el operador SORT y se utiliza el ndice no clster que se acaba de crear.
Motor de base de datos puede moverse con la misma eficacia en cualquier direccin. Un ndice definido como (RejectedQty DESC, ProductID ASC) se puede seguir utilizando para una consulta en la que se invierte la direccin de ordenacin de las columnas en la clusula ORDER BY. Por ejemplo, una consulta con la clusula ORDER BYORDER BY RejectedQty ASC, ProductID DESC puede utilizar el ndice. Solo se pueden especificar criterios de ordenacin para columnas de clave. La vista de catlogo sys.index_columns y la funcin INDEXKEY_PROPERTY informan de si una columna de ndice est almacenada en orden ascendente o descendente. [Arriba]
Nota
Cuando crea una restriccin PRIMARY KEY, se crea automticamente un ndice nico en las column es clster; sin embargo, puede especificar un ndice no clster cuando crea la restriccin.
Se pueden utilizar en consultas por rango. Si el ndice clster no se crea con la propiedad UNIQUE, el Motor de base de datos agrega automticamente una columna de valor de unicidad de 4 bytes a la tabla.Cuando es necesario, el Motor de base de datos agrega automticamente un valor de unicidad a una fila para hacer que cada clave sea nica. Esta columna y sus valores se utilizan de forma interna; los usuarios no pueden verlos ni tener acceso a ellos.
conocen en conjunto como niveles intermedios. En un ndice clster, los nodos hoja contienen las pginas de datos de la tabla subyacente. El nodo raz y los nodos intermedios incluyen pginas de ndice que contienen filas de ndice. Cada fila de ndice contiene un valor clave y un puntero a una pgina de nivel intermedio en el rbol b, o bien a una fila de datos del nivel hoja del ndice. Las pginas de cada nivel del ndice se vinculan en una lista con vnculos dobles. Los ndices clster tienen una fila en sys.partitions, con index_id = 1 para cada particin utilizada por el ndice. De forma predeterminada, un ndice clster tiene una sola particin. Cuando un ndice clster tiene mltiples particiones, cada particin tiene una estructura de rbol b que contiene los datos de esa particin especfica. Por ejemplo, si un ndice clster tiene cuatro particiones, hay cuatro estructuras de rbol b, una en cada particin. En funcin de los tipos de datos del ndice clster, cada estructura de ndice clster tendr una o ms unidades de asignacin en las que almacenar y administrar los datos de una particin especfica. Como mnimo, cada ndice clster tendr una unidad de asignacin IN_ROW_DATA por particin. El ndice clster tambin tendr una unidad de asignacin LOB_DATA por particin si contiene columnas de objetos grandes (LOB). Tambin tendr una unidad de asignacin ROW_OVERFLOW_DATA por particin si contiene columnas de longitud variable que superen el lmite de tamao de fila de 8.060 bytes. Las pginas de la cadena de datos y las filas que contienen se ordenan segn el valor de la clave de ndice clster. Todas las inserciones se hacen en el punto en el que el valor de clave de la fila insertada quede dentro de la secuencia de orden entre las filas existentes. En esta ilustracin se muestra la estructura de un ndice clster en una sola particin.
bsqueda. Los ndices no clster definidos en la misma tabla sern bastante ms grandes, ya que sus entradas contienen la clave de agrupacin en clsteres y las columnas de clave definidas para dicho ndice no clster. [Arriba]
por particin encargada de almacenar las pginas de rbol b del ndice. El ndice no clster tambin tendr una unidad de asignacin LOB_DATA por particin si contiene columnas de objetos grandes (LOB). Tambin tendr una unidad de asignacin ROW_OVERFLOW_DATA por particin si contiene columnas de longitud variable que superen el lmite de tamao de fila de 8.060 bytes. En la siguiente ilustracin se muestra la estructura de un ndice no clster en una sola particin.
Las aplicaciones y bases de datos de procesamiento de transacciones en lnea (OLTP) que contienen tablas deben evitar el exceso de ndices. Adems, los ndices deben ser estrechos, es decir, con la menor cantidad de columnas posible. Si se utiliza un gran nmero de ndices en una tabla, el rendimiento de las instrucciones INSERT, UPDATE, DELETE y MERGE se ver afectado, ya que todos los ndices deben ajustarse adecuadamente a medida que cambian los datos de la tabla.
localizar todos los valores de las columnas del ndice, sin tener acceso a los datos de la tabla o del ndice clster, lo que da como resultado menos operaciones de E/S de disco.
Nota
Cuando un ndice contiene todas las columnas a las que hace referencia la consulta, normalmente se dice que
Las columnas de clave se almacenan en todos los niveles del ndice, mientras que las columnas sin clave solo se almacenan en el nivel hoja.
Las columnas de clave de ndice, excluyendo las sin clave, deben seguir las restricciones de tamao de ndice existentes de 16 columnas de clave como mximo y un tamao de las claves de ndice total de 900 bytes. El tamao total de todas las columnas sin clave solo est limitado por el tamao de las columnas especificadas en la clusula INCLUDE; por ejemplo, las columnasvarchar(max) estn limitadas a 2 GB.
Recomendaciones de diseo
Redisee ndices no clster con un tamao de las claves de ndice grande para que solo las columnas utilizadas para bsquedas sean columnas de clave. Haga que todas las dems columnas que abarcan la consulta sean columnas sin clave incluidas. De esta forma, tendr todas las columnas necesarias para abarcar la consulta pero la clave de ndice en s ser pequea y eficaz. Por ejemplo, suponga que desea disear un ndice para abarcar la siguiente consulta. SELECT AddressLine1, AddressLine2, City, StateProvinceID, PostalCode FROM Person.Address WHERE PostalCode BETWEEN N'98000' and N'99999'; Para abarcar la consulta, cada columna debe definirse en el ndice. Aunque puede definir todas las columnas como columnas de clave, el tamao de clave debe ser de 334 bytes. Como la nica columna que se usa de verdad como criterio de bsqueda es la columna PostalCode, que tiene una longitud de 30 bytes, un mejor diseo del ndice definira PostalCode como columna de clave e incluira todas las dems columnas como columnas sin clave. La siguiente instruccin crea un ndice con columnas incluidas para abarcar la consulta. CREATE INDEX IX_Address_PostalCode ON Person.Address (PostalCode) INCLUDE (AddressLine1, AddressLine2, City, StateProvinceID);
Consideraciones de rendimiento
Evite agregar columnas que no sean necesarias. El hecho de agregar demasiadas columnas de ndice, con o sin clave, puede tener las siguientes consecuencias en el rendimiento: Cabrn menos filas de ndice en una pgina. Esto puede crear incrementos de E/S y una reduccin de la eficacia de la cach. Se necesitar ms espacio en disco para almacenar el ndice. En concreto, al agregar los tipos de datos varchar(max), nvarchar(max), varbinary(max) o xml como columnas de ndice sin clave, se pueden aumentar significativamente los requisitos de espacio en
disco. Esto se debe a que los valores de columnas se copian en el nivel hoja del ndice. Por lo tanto, residen en el ndice y en la tabla base. Puede que el mantenimiento del ndice haga aumentar el tiempo necesario para realizar operaciones de modificacin, insercin, actualizacin o eliminacin en la tabla subyacente o la vista indizada. Debe determinar si la mejora del rendimiento de las consultas compensa el efecto en el rendimiento durante la modificacin de datos y en los requisitos de espacio en disco adicionales. [Arriba]
Consideraciones
Un ndice nico, una restriccin UNIQUE o una restriccin PRIMARY KEY no se pueden crear si existen valores de clave duplicados en los datos. Si los datos son nicos y desea hacer cumplir la exclusividad, la creacin de un ndice nico en lugar de un ndice no nico en la misma combinacin de columnas proporciona informacin adicional para el optimizador de consultas que puede dar como resultado unos planes de ejecucin ms eficaces. En este caso se recomienda crear un ndice nico (preferiblemente mediante una restriccin UNIQUE). Un ndice no clster nico puede incluir columnas sin clave. Para obtener ms informacin, vea ndice con columnas incluidas. [Arriba]
Consideraciones de diseo
Para disear ndices filtrados efectivos, es importante entender qu consultas utiliza la aplicacin y cmo se relacionan con los subconjuntos de datos. Algunos ejemplos de datos que tienen subconjuntos bien definidos son las columnas con una mayora de valores NULL, las columnas con categoras de valores heterogneas y las columnas con intervalos de valores diferenciados. Las siguientes consideraciones del diseo proporcionan una variedad de escenarios en los que un ndice filtrado puede ofrecer ventajas sobre los ndices de tabla completa.
WHERE ProductSubcategoryID >= 27 AND ProductSubcategoryID <= 36; El ndice filtrado FIProductAccessories abarca la consulta siguiente porque los resultados de las consultas se incluyen en el ndice y el plan de consulta no incluye bsquedas en una tabla base. Por ejemplo, la expresin de predicado de la consulta ProductSubcategoryID = 33es un subconjunto del predicado del ndice filtrado ProductSubcategoryID >= 27 y ProductSubcategoryID <= 36 , las columnas ProductSubcategoryID y ListPrice del predicado de la consulta son ambas columnas de clave del ndice, y el nombre se almacena en el nivel hoja del ndice como una columna incluida. SELECT Name, ProductSubcategoryID, ListPrice FROM Production.Product WHERE ProductSubcategoryID = 33 AND ListPrice > 25.00 ;
Columnas de clave
Se recomienda insertar un nmero pequeo de columnas incluidas o de clave en la definicin de un ndice filtrado e incorporar solamente las columnas necesarias para que el optimizador de consultas elija el ndice filtrado para el plan de ejecucin de consultas. El optimizador de consultas puede elegir un ndice filtrado para la consulta, independientemente de que cubra la consulta o no. Sin embargo, es ms probable que el optimizador de consultas elija un ndice filtrado si cubre la consulta. En algunos casos, un ndice filtrado cubre la consulta sin incluir las columnas en la expresin del ndice filtrado como columnas incluidas o de clave en la definicin del ndice filtrado. Las instrucciones siguientes explican los casos en que una columna de la expresin del ndice filtrado debe ser una columna incluida o de clave en la definicin del ndice filtrado. Los ejemplos hacen referencia al ndice filtrado FIBillOfMaterialsWithEndDate que se cre previamente. Una columna de la expresin del ndice filtrado no tiene por qu ser una columna incluida o de clave en la definicin del ndice filtrado cuando la expresin del ndice filtrado es equivalente al predicado de la consulta y la consulta no devuelve la columna de la expresin del ndice filtrado con los resultados de la consulta. Por ejemplo,FIBillOfMaterialsWithEndDate cubre la consulta siguiente porque el predicado de consulta es equivalente a la expresin del filtro, y EndDate no se devuelve con los resultados de la consulta. FIBillOfMaterialsWithEndDate no necesita EndDate como una columna incluida o de clave en la definicin del ndice filtrado. SELECT ComponentID, StartDate FROM Production.BillOfMaterials WHERE EndDate IS NOT NULL; Una columna de la expresin del ndice filtrado debe ser una columna incluida o de clave de la definicin del ndice filtrado cuando el predicado de la consulta usa la columna en una comparacin no equivalente a la expresin del ndice filtrado. Por ejemplo, FIBillOfMaterialsWithEndDate es vlido para la consulta siguiente porque selecciona un subconjunto de filas del ndice filtrado. Sin embargo, no cubre la consulta siguiente porque EndDate se utiliza en la comparacin EndDate > '20040101', que no es equivalente a la expresin del ndice filtrado. El procesador de consultas no puede ejecutar esta consulta si no busca los valores de EndDate. Por lo tanto, EndDatedebe ser una columna incluida o de clave de la definicin del ndice filtrado. SELECT ComponentID, StartDate FROM Production.BillOfMaterials WHERE EndDate > '20040101'; Una columna de la expresin del ndice filtrado debe ser una columna incluida o de clave en la definicin del ndice filtrado si la columna est en el conjunto de resultados de la consulta. Por ejemplo, FIBillOfMaterialsWithEndDate no atiende la consulta siguiente porque devuelve la
columna EndDate en los resultados de la consulta. Por tanto, EndDate debe ser una columna incluida o de clave de la definicin del ndice filtrado. SELECT ComponentID, StartDate, EndDate FROM Production.BillOfMaterials WHERE EndDate IS NOT NULL; La clave de ndice clster de la tabla no tiene por qu ser una columna incluida o de clave de la definicin del ndice filtrado. La clave de ndice cluster se incluye de forma automtica en todos los ndices no clster, incluidos los ndices filtrados.