Sunteți pe pagina 1din 11

Captulo 4

Gestin de los ndices nivel


avanzado

Objetivo

Analizar algunas tcnicas avanzadas de indexacin.


Identificar los ndices especiales disponibles en SQL Server.

Temas

1.
2.

Tcnicas avanzadas de indexacin


Tipos de ndices especiales.

Cibertec Per S.A.C - Transact-SQL - SQL Server 2014

Gestin de los ndices nivel avanzado

1.

34

Tcnicas avanzadas de indexacin

Covering Indexes
Ser revisado mediante un ejemplo.
1. En la tabla Person.Address, ejecutar lo siguiente:
sp_helpindex 'Person.Address'

2. Registrar la informacin obtenida. Ejecutar la sentencia.


set statistics io on
go
Select
a.PostalCode
from
Person.Address a
where a.StateProvinceID = 42
go
set statistics io off;

3. Revisar la informacin estadstica y los Planes de Ejecucin. Luego, registrar dicha


informacin.
Como se observa en el resultado final, s se utiliza el ndice; sin embargo, si query
solo retornace la columna StateProvinceID, no se tendra mayor problema. Se podra
realizar el cambio en el query anterior para satisfacer este requerimiento,
lastimosamente el query requiere otro campo que forma parte del ndice, una posible
solucin sera la de incluir el campo PostalCode dentro del ndice de la columna
StateProvinceID, sin embargo, si ms adelante se requiere otro campo, sera
necesario agregarlo y as sucesivamente, lo que ocasionara un ndice con

Cibertec Per S.A.C - Transact-SQL - SQL Server 2014

Gestin de los ndices nivel avanzado

35

demasiados campos y que no se podra reusar para otros queries solo para ste, por
la cantidad de columnas que forman parte del ndice.
Para este caso se presenta un key lookup, para poder traer el valor de PostalCode,
que es necesario para satisfacer el query,
4. Modificar el ndice existente para poder cubrir la consulta solicitada, ejecutar el
siguiente script:
create nonclustered index IX_Address_StateProvinceID
on
person.Address (StateProvinceID asc)
Include (PostalCode)
with (DROP_EXISTING = ON)

5. Revisar la informacin estadstica del query, en el Plan de Ejecucin.


set statistics io on
go
Select
a.PostalCode
from
Person.Address a
where a.StateProvinceID = 42
go
set statistics io off;

Se puede observar una gran disminucin de los reads y el uso del ndice satisface el query. Al
volver a revisar los ndices de la tabla, se ver que:
sp_helpindex 'Person.Address'
Se adicionan columnas al ndice usando INCLUDE, esto sin tener que alterar el nmero de
columnas del ndice, porque se almacenan solo a nivel de la ltima hoja del rbol del ndice.
La opcin INCLUDE puede ser utilizada:

Cuando no se quiere incrementar el tamao de las keys del ndice, pero se quiere tener un
covering index.
Cuando se est indexando un tipo de dato que no puede ser indexado (excepto ntext, text,
image)
Cuando ya se ha excedido, el mximo nmero de key columns para un ndice.

Antes de construir una gran cantidad de covering indexes, considerar cmo SQL Server puede
crear covering indexes on the fly usando index intersection.

1.2

Index intersections
Usar mltipes ndices nonclustered para satisfacer todos los requerimientos de
columnas de una tabla para un query.
Si una tabla tiene mltiples ndices, entonces SQL Server tratar de usarlos para ejecutar
un query.
Se analizar el siguiente query, para ello, se debe obtener un Plan de Ejecucin
Select
*
from
Sales.SalesOrderHeader soh
where soh.SalesPersonID = 276
and soh.OrderDate between '4/1/2007' and '7/1/2007'

Cibertec Per S.A.C - Transact-SQL - SQL Server 2014

Gestin de los ndices nivel avanzado

36

Se puede apreciar que para la clusula Where, la tabla debe de tener un ndice sobre
ambos casos para que pueda ser utilizada; sin embargo, si se analizan los ndices
existentes. Para dicha tabla se puede observar lo siguiente:
sp_helpindex 'Sales.SalesOrderHeader'
La tabla tiene un ndice nonclustered sobre la columna SalesPersonID, pero no tiene un
ndice sobre la columna OrderDate.
Revisando el Plan de Ejecucin previamente obtenido, se observa que el ndice que
existe sobre la columna SalesPersonID no est siendo usado, puesto que se necesita
tambin el valor de la columna OrderDate, por lo cual el Query Optimizer de SQL Server
decide utilizar al ndice clustered para retornar todos los valores y realizar el filtro
respecitvo del Where.
Lo ideal sera agregar la columna OrderDate al ndice, pero se puede afectar por la
modificacin a otros queries, pero, por qu mejor no crear un ndice nonclustered sobre
la columna que falta, para ello, ejecutar el siguiente script:
Create
nonclustered
index
Sales.SalesOrderHeader(OrderDate)SalesPersonID,OrderDate

IDX

on

Volver a revisar el Plan de Ejecucin del siguiente query:


Select
*
fromSalesPersonID,OrderDate
Sales.SalesOrderHeader soh
where soh.SalesPersonID = 276
and soh.OrderDate between '4/1/2007' and '7/1/2007'

Ahora, se puede apreciar que SQL Server aprovecha ambos ndices para obtener la
informacin con este tipo de estrategia de indexacin, podemos aprovechar cada ndice
por separado en otras consultas o ambas como en este caso.
Eliminar el ndice creado.
drop index IDX on Sales.SalesOrderHeader

1.3

Index joins
Es una variacin de la tcnica anterior; para poder apreciar mejor esta tcnica usaremos
el siguiente query.
Select
soh.SalesPersonID, soh.OrderDate
from
Sales.SalesOrderHeader soh
where soh.SalesPersonID = 276
and soh.OrderDate between '4/1/2005' and '7/1/2005'

Se obtiene el Plan de Ejecucin y se observa que, al igual que el caso anterio,r el Query
Optimizer no utiiliza el ndice existente sobre SalesPersonID (para revisar los ndices
utilizar el procedimiento almacenado de sistem sp_HelpIndex), por lo cual se debe
decidir, utilizar el ndice clustered creado.

Cibertec Per S.A.C - Transact-SQL - SQL Server 2014

Gestin de los ndices nivel avanzado

37

Para poder analizar mejor esta estrategia es necesario obtener la informacin estadstica
de lecturas, para lo cual se ejecuta el query anterior dentro de:
set statistics io on y set statistics io off
(*) Registrar el valor obtenido en el tab messages.
Y ahora, se crear el ndice sobre la columna OrderDate para poder tener, como en el
caso anterior, interseccin de ndices.
create nonclustered index IDX on Sales.SalesOrderHeader(OrderDate)

Revisar nuevamente, el plan de ejecucin del query y la informacin estadstica de


lecturas, para lo cual se utiliza el siguiente query:
set statistics io on
go
Select
soh.SalesPersonID, soh.OrderDate
from
Sales.SalesOrderHeader soh
where soh.SalesPersonID = 276
and soh.OrderDate between '4/1/2005' and '7/1/2005'
go
y set statistics io off

Se observa gran disminucin de lecturas lgicas, debido a que los dos ndices actan
como un covering index, reduciendo las lecturas lgicas a 2 index seeks en lugar de un
scan al indice clustered.
Ahora a eliminar el ndice creado.
drop index IDX on Sales.SalesOrderHeader

1.4

Filtered Indexes
Es un ndice nonclustered que usa un filtro, bsicamente una sentencia WHERE, por
ejemplo una columna con muchos valores NULL, se puede tener un filtered index sobre
la columna para tener un ndice solo sobre la data que no es NULL.
Por ejemplo, la tabla Sales.
Sales.SalesOrderHeader, tiene ms de 30 000 filas, de las cuales ms del 25% de filas
tienen valores NULL en las columnas PurchaseOrderNumber y SalesPersonId, si se
desea obtener la siguiente informacin de ventas con el query que se muestra a
continuacin, revisar su plan de ejecucin y la informacin estadstica:
set statistics io on
go
Select
soh.PurchaseOrderNumber,
soh.OrderDate,
soh.ShipDate,
soh.SalesPersonID
from Sales.SalesOrderHeader soh
where soh.PurchaseOrderNumber like 'PO5%'
and soh.SalesPersonID is not null
go
set statistics io off;

Cibertec Per S.A.C - Transact-SQL - SQL Server 2014

Gestin de los ndices nivel avanzado

38

Revisando la informacin estadstica y el Plan de Ejecucin es recomendable crear un


ndice nonclustered, incluyendo las otras columnas para cubrir el query. Para esto, se
crear el siguiente ndice:
create nonclustered index IDX on Sales.SalesOrderHeader(purchaseOrderNumber, SalesPersonId)
INCLUDE (OrderDate,ShipDate);

Al volver a revisar el Plan de Ejecucin y las estadsticas, se puede observar que


mejoraron las lecturas y que ahora se est utilizando el ndice creado. Para mejorar el
query, el dato inicial de tener ms del 75% de valores nulls para algunos campos es de
vital importancia, ya que con dicha informacin se puede ajustar al ndice para que filtre
los valores null, reduciendo el nmero de pginas a ser utilizadas por el ndice, para ello,
modificar el ndice con lo siguiente:
Create nonclustered index IDX on Sales.SalesOrderHeader(purchaseOrderNumber, SalesPersonId)
Include (OrderDate, ShipDate)
Where purchaseOrderNumber IS NOT NULL
And SalesPersonId IS NOT NULL WITH (DROP_EXISTING = ON)

Volver a revisar el query original con el plan de ejecucin y la informacin estadstica:


set statistics io on
go
Select
soh.PurchaseOrderNumber,
soh.OrderDate,
soh.ShipDate,
soh.SalesPersonID
from Sales.SalesOrderHeader soh
where soh.PurchaseOrderNumber like 'PO5%'
and soh.SalesPedrop index Sales.SalesOrderHeader.IDXrsonID is not null
go
set statistics io off;

Si bien el plan de ejecucin no ha tenido mayores cambios, s se redujo de 5 a 4 las


lecturas, este impacto no es tan grande para este ejemplo, es del 20%, pero al hablar de
un query que demora minutos un 20%, es considerable.
Ahora, se debe eliminar el ndice.
drop index IDX on Sales.SalesOrderHeader

1.5

Index Compression
La compresin de ndices y de data fue introducida en la versin 2008 (Edicin
Enterprise y Develoer).
Tener una compresin de ndices es, bsicamente, tener ms informacin en una sola
pgina de datos, esto significa tener que utilizar menos pginas; sin embargo, es un
arma de doble filo pues se puede tener menos pginas para almacenar un ndice, pero
impacta en CPU y Memoria, que son los recursos ms utilizados al momento de la
compresin y descompresin.

Cibertec Per S.A.C - Transact-SQL - SQL Server 2014

Gestin de los ndices nivel avanzado

39

Crear los siguientes ndices:


CREATE NONCLUSTERED INDEX IDX1
ON Person.Address(City ASC, PostalCode ASC) ;
CREATE NONCLUSTERED INDEX IDX2
ON Person.Address (City,PostalCode)
WITH (DATA_COMPRESSION = ROW ) ;
CREATE NONCLUSTERED INDEX IDX3
ON Person.Address (City,PostalCode)
WITH (DATA_COMPRESSION = PAGE) ;

Para observar cmo se encuentra el almacenamiento de los ndices, a nivel de pgina de


datos, ejecutar el siguiente query.
SELECT i.Name,
i.type_desc,
s.page_count,
s.record_count,
s.index_level,
compressed_page_count
FROM sys.indexes i
JOIN sys.dm_db_index_physical_stats(DB_ID(N'AdventureWorks2008R2'),
OBJECT_ID(N'Person.Address'), NULL,
NULL, 'DETAILED') AS s
ON i.index_id = s.index_id
WHERE i.OBJECT_ID = OBJECT_ID(N'Person.Address') ;

Para poder revisar el nmero de lecturas por cada ndice, se debe forzar al query original
para que utilice un determinado ndice y ejecutar cada una de las siguientes sentencias,
registrando los valores estadsticos de las lecturas para armar un cuadro comparativo al
final:
SELECT a.City,
a.PostalCode
FROM Person.Address AS a WITH (INDEX = IDX1)
WHERE a.City = 'Newton'
AND a.PostalCode = 'V2M1N7' ;
SELECT a.City,
a.PostalCode
FROM Person.Address AS a WITH (INDEX = IDX2)
WHERE a.City = 'Newton'
AND a.PostalCode = 'V2M1N7' ;
SELECT a.City,
a.PostalCode
FROM Person.Address AS a WITH (INDEX = IDX3)
WHERE a.City = 'Newton'
AND a.PostalCode = 'V2M1N7' ;

Cibertec Per S.A.C - Transact-SQL - SQL Server 2014

Gestin de los ndices nivel avanzado

40

Cuadro comparativo:
Escenario

Informacin estadstica

IDX1

Scan count ___, logical reads ___, physical reads __, read-ahead
reads __, lob logical reads __, lob physical reads __, lob read-ahead
reads __.

IDX2

Scan count ___, logical reads ___, physical reads __, read-ahead
reads __, lob logical reads __, lob physical reads __, lob read-ahead
reads __.

IDX3

Scan count ___, logical reads ___, physical reads __, read-ahead
reads __, lob logical reads __, lob physical reads __, lob read-ahead
reads __.

Ahora, eliminar los ndices creados anteriormente; para ello, ejecutar el siguiente query:
DROP INDEX Person.Address.IDX1;
DROP INDEX Person.Address.IDX2;
DROP INDEX Person.Address.IDX3;

1.6

ColumnStore Index
Esta nueva estrategia de indexacin es propia de la versin SQL Server 2012. Este tipo
de ndice, realiza la indexacin de la data por columnas, en lugar de hacerlo por filas,
esta nueva caracterstica es muy til y agrega mejor rendimiento a los entornos de
datawarehouse, donde se tiene gran cantidad de data en las tablas.
La informacin almacenada dentro de un ndice de tipo ColumnStore, es agrupada en
cada columna y estos agrupamientos son almacenados individualmente.
Algunas limitaciones cuando se utilizan los ndices ColumnStore son:

Las columnas que tienen este tipo de ndices no pueden ser actualizados (lo que es
un comportamiento normal de las bases de datos datawarehouse), para poder
realizar una actualizacion, primero se debe eliminar el ndice ColumnStore.
No se puede utilizar ciertos tipos de datos en estos ndices como: binary, text,
varchar(max), uniqueidentifier, xml, tipos de datos clr o decimales con una precisin
mayor a 18.
No se puede crear un ndice ColumnStore sobre una columna Sparse.
No se puede crear este tipo de ndices sobre vistas.

En la base de datos AdventureWorks2008R2, una tabla que sirve para almacenar


informacin histrica, no sufre actualizaciones constantes, pero s cargas y lecturas
constantes, con lo cual es un buen candidato para tener un ndice ColumnStore, este es
el query que se consulta habitualmente:
Set statistics io on
go
SELECT tha.ProductID,
COUNT(tha.ProductID) AS CountProductID,
SUM(tha.Quantity) AS SumQuantity,
AVG(tha.ActualCost) AS AvgActualCost
FROM Production.TransactionHistoryArchive AS tha
GROUP BY tha.ProductID ;
go
Set statistics io on

Cibertec Per S.A.C - Transact-SQL - SQL Server 2014

Gestin de los ndices nivel avanzado

41

Registrar la informacin estadstica de lecturas y analizar el plan de ejecucin. Crear el


ndice columnstore, para lo cual se ejecuta el siguiente script:
CREATE NONCLUSTERED COLUMNSTORE INDEX ix_csTest
ON Production.TransactionHistoryArchive
(ProductID,
Quantity,
ActualCost) ;

Con el ndice columnStore creado, el query optimizer ahora tiene la opcin de usar ese
ndice para satisfacer el query previo. Para obtener el beneficio de usar este nuevo tipo
de ndice, se debe de ejecutar el query:
Set statistics io on
go
SELECT tha.ProductID,
COUNT(tha.ProductID) AS CountProductID,
SUM(tha.Quantity) AS SumQuantity,
AVG(tha.ActualCost) AS AvgActualCost
FROM Production.TransactionHistoryArchive AS tha
GROUP BY tha.ProductID ;
go
Set statistics io on

La reduccin radical de lecturas solicitadas para obtener el resultado del query, es la que
permitir obtener, de manera ms rpida, la informacin usando un ndice columnStore,
ahora esta tabla est indexada por columnas en lugar de filas.

Cibertec Per S.A.C - Transact-SQL - SQL Server 2014

Gestin de los ndices nivel avanzado

2.

42

Tipos de ndices especiales

Full-Text
Para poder almacenar gran cantidad de texto en SQL Server se utiliza el tipo de dato
Varchar, Nvarchar, Char y Nchar con el valor MAX, un ndice clustered o nonclustered
no puede ser creado sobre ese tipo de columnas. Para poder indexar este tipo de
columnas y obtener bsquedas sobre stas, de manera ms rpida se tiene que
implementar la bsqueda por Full-Text, utilizando el full text engine se puede crear
ndices de tipo full-text, tambin se pueden crear ndices de este tipo sobre tipos de
datos Varbinary o Bigint.
Con este tipo de ndice las consultas se pueden realizar de manera similar a la del
buscador google, es decir, al colocar una palabra, la bsqueda ubicar las palabras que
se asemejen, esto dependiendo del idioma con el cual se realiz la configuracin del
FullText Srarch.

Spatial
Presentado con SQL Server 2008, ahora es posible almacenar datos espaciales
(spatial data), este tipo de datos puede ser de tipo geomtrico o de tipo geogrfico
(literalmente especificando un punto en la tierra); realizar una indexacin sobre una
columna con este tipo dato es complicado, por lo cual, se debe de crear un ndice
especifico.
Un ndice espacial solo se puede crear sobre columnas de este tipo; la tabla base no
debe tener vistas indexadas asociadas, solo debe de tener un primary key, adems, se
pueden crear hasta 249 ndices espaciales sobre alguna columna de una tabla.

Cibertec Per S.A.C - Transact-SQL - SQL Server 2014

Gestin de los ndices nivel avanzado

43

XML
Presentado como tipo de dato en SQL Server 2005.
XML es almacenado como data de texto well-formed dentro de SQL Server, la data de
estas columnas puede ser consultada usando xQuery; respecto a la indexacin existen
algunos que han sido definidos y creados para este tipo de dato, Una columna con un
tipo de dato XML puede tener un principal y varios secundarios ndices, el XML primario
parte las propiedades, atributos y elementos de la data del XML y lo almacena como
una tabla interna. Debe existir un primary key en la tabla y debe de ser clustered para
poder crear un ndice XML, despus que el ndice XML es creado, los ndices
secundarios pueden ser creados, stos tienen informacin como los Paths, Values,
Properties del XML.

Cibertec Per S.A.C - Transact-SQL - SQL Server 2014

S-ar putea să vă placă și