Bookmark Lookup , por que ?

24/05/2007 - 18:49 por Penta | Informe spam
Estimados.
Leyendo unos valiosos articulos sobre "UPDATE STATISTICS" de Don
Alejandro Mesa me puse a probar
Todo esto en un servidor de pruebas SQL 2000 SP4.
En la siguiente query me indica que hace un Bookmark Lookup.

SELECT C.CODCARR, C.NOMBRE_C
FROM MT_CARRER C
INNER JOIN MT_ALUMNO A ON A.CODCARPR=C.CODCARR
WHERE A.ESTACAD='VIGENTE' AND A.ANO_MAT 07 and
a.codcarpr='11000'
GROUP BY C.CODCARR, C.NOMBRE_C
ORDER BY NOMBRE_C


No se como mostrar el plan de ejecucion como texto, asi que lo
escribire aca:

Select - Stream Aggregat Nested Loops -
MT_carrer.IX_MT_CARRER
0 % 0%
0% 1%
-
Filter -- Bookmark Lookup - MT_Alumno.IX_MT_ALUMNO11

1% 98% 1%

Con dichos datos cree un indice en la tabla MT_CARRER codcarr,nombre_c

Pero Aun asi sigo
Que estoy haciendo mal ?
Lei los articulos de Don Alejandro Mesa, y entendi entre otras cosas
que "SQL Server debe hacer una operación "Bookmark lookup" (ir a leer
la data en la tabla)" con eso entiendo que hay algo "malo" o falta
algun indice ? si encuentra un Bookmark Lookup ?

Les agradeceria su valioso aporte.

Atte,
Cristian.
 

Leer las respuestas

#1 Alejandro Mesa
24/05/2007 - 21:10 | Informe spam
Penta,

No se como mostrar el plan de ejecucion como texto, asi que lo
escribire aca:



SET SHOWPLAN_TEXT ON;

Lei los articulos de Don Alejandro Mesa, y entendi entre otras cosas
que "SQL Server debe hacer una operación "Bookmark lookup" (ir a leer
la data en la tabla)" con eso entiendo que hay algo "malo" o falta
algun indice ? si encuentra un Bookmark Lookup ?



Una tabla puede tener dos tipos de indices, clustered y nonclustered, pero
solamente puede tener un unico indice clustered, el cual contiene la data
almacenada, en sus nodos hojas. En cambio, la tabla puede tener hasta 249
indices nonclustered (SS 2000), pero estos contienen un valor que apunta a la
data en la tabla o al indice clustered y por lo tanto cuando se usa un indice
nonclustered que no cubre todas las columnas referenciadas en el query, se
necesita hacer una operacion "bookmark lookup" para leer la data, osea, se
necesita saltar a la tabla o indice clustered para leer la data.

Se puede evitar esta operacion si el indice cubre todas las columnas
referenciadas en el query, con lo cual se debe tener mucho cuidado (cuando
crear un covering index), o si la lectura se realiza directamente en el
indice clustered. Esto no significa que evitar esta operacion siempre es
bueno y pongo como ejemplo un query donde se filtra por columnas que no
forman parte del indice clustered, pero no se tiene indice nonclustered. En
este caso, SQL Server tendra que escanear todo el indice clustered para
averiguar por las columnas que aparecen en el filtro y lo tendra que hacer
aunque la selectividad de ese filtro sea alta (pocas filas machan la
condicion). Si ahora creamos un indice nonclustered por esas columnas, se
hara una operacion quizas "index seek" en el indice nonclustered y
seguidamente una operacion "bookmark lookup", las cuales posiblemente arrojen
menos lecturas que cuando no se tenia el indice nonclustered.

Ejemplo:

use northwind
go

select *
into dbo.orders_1
from dbo.orders
go

alter table dbo.orders_1
add constraint pk_orders_1 primary key clustered (orderid)
go

update statistics dbo.orders_1 with fullscan, all
go

checkpoint
go

dbcc freeproccache
dbcc dropcleanbuffers
go

select
customerid, orderid, orderdate
from
dbo.orders_1
where
customerid = 'CENTC'
go

dbcc freeproccache
dbcc dropcleanbuffers
go
set statistics io on
go

select
customerid, orderid, orderdate
from
dbo.orders_1
where
customerid = 'CENTC'
go

set statistics io off
go

create index orders_1_customerid_nu_nc_ix
on dbo.orders_1(customerid)
go

checkpoint
go

dbcc freeproccache
dbcc dropcleanbuffers
go

select
customerid, orderid, orderdate
from
dbo.orders_1
where
customerid = 'CENTC'
go

dbcc freeproccache
dbcc dropcleanbuffers
go
set statistics io on
go

select
customerid, orderid, orderdate
from
dbo.orders_1
where
customerid = 'CENTC'
go

set statistics io off
go

drop table dbo.orders_1
go

Estos son los valores de estadisticas de IO que obtengo:

1 - scan del indice clustered

Table 'orders_1'. Scan count 1, logical reads 21, physical reads 2,
read-ahead reads 12.

2 - "index seek" en el nonclustered seguido por "bookmark lookup"

Table 'orders_1'. Scan count 1, logical reads 4, physical reads 3,
read-ahead reads 0.


En el scan del indice clustered, se leyeron 14 paginas desde disco:

physical reads 2
read-ahead reads 12

En la operacion "index seek" del nonclustered y "bookmark lookup" solo 3.

physical reads 3



AMB








"Penta" wrote:

Estimados.
Leyendo unos valiosos articulos sobre "UPDATE STATISTICS" de Don
Alejandro Mesa me puse a probar
Todo esto en un servidor de pruebas SQL 2000 SP4.
En la siguiente query me indica que hace un Bookmark Lookup.

SELECT C.CODCARR, C.NOMBRE_C
FROM MT_CARRER C
INNER JOIN MT_ALUMNO A ON A.CODCARPR=C.CODCARR
WHERE A.ESTACAD='VIGENTE' AND A.ANO_MAT 07 and
a.codcarpr='11000'
GROUP BY C.CODCARR, C.NOMBRE_C
ORDER BY NOMBRE_C


No se como mostrar el plan de ejecucion como texto, asi que lo
escribire aca:

Select - Stream Aggregat Nested Loops -
MT_carrer.IX_MT_CARRER
0 % 0%
0% 1%
-
Filter -- Bookmark Lookup - MT_Alumno.IX_MT_ALUMNO11

1% 98% 1%

Con dichos datos cree un indice en la tabla MT_CARRER codcarr,nombre_c

Pero Aun asi sigo >
Que estoy haciendo mal ?
Lei los articulos de Don Alejandro Mesa, y entendi entre otras cosas
que "SQL Server debe hacer una operación "Bookmark lookup" (ir a leer
la data en la tabla)" con eso entiendo que hay algo "malo" o falta
algun indice ? si encuentra un Bookmark Lookup ?

Les agradeceria su valioso aporte.

Atte,
Cristian.


Preguntas similares