Afectan los null a los índices?

15/01/2008 - 15:52 por xurxof | Informe spam
Aunque el problema ya ha sido solucionado, hoy me he encontrado con
una situación que no alcanzo a comprender. No soy un usuario
experimentado de SQL Server, pero no encuentro nada que pueda explicar
el siguiente comportamiento:
Tengo una tabla y deseo saber el el valor máximo de una fecha para
varios registros. Dependiendo de como construya cierto índice, SQL
Server es capaz de localizar el registro. En el primer caso el campo
fecha se ordena ascendente y la instrucción SELECT no devuelve ningún
registro. Si el campo se indexa descendentemente lo encuentra sin
problema. Veamos:


CREATE NONCLUSTERED INDEX
[IX_PedidosComprasLineas_IdPedidoCompra_PclFechaPrevistaRecepcion_] ON
[dbo].[PedidosComprasLineas]
(
[IdPedidoCompra] ASC,
[PclFechaPrevistaRecepcion] DESC

)WITH FILLFACTOR = 90 ON [PRIMARY]



SELECT IdPedidoCompra, MAX(PclFechaPrevistaRecepcion) AS
FechaPrevistaRecepcion
FROM dbo.PedidosComprasLineas
GROUP BY IdPedidoCompra
HAVING (IdPedidoCompra B962)


IdPedidoCompra FechaPrevistaRecepcion
42962 NULL
Advertencia: valor NULL eliminado por el agregado u otra operación
SET.

(1 filas afectadas)





Sin embargo:



CREATE NONCLUSTERED INDEX
[IX_PedidosComprasLineas_IdPedidoCompra_PclFechaPrevistaRecepcion]
ON [dbo].[PedidosComprasLineas]
(
[IdPedidoCompra] ASC,
[PclFechaPrevistaRecepcion] ASC

)WITH FILLFACTOR = 90 ON [PRIMARY]



SELECT IdPedidoCompra, MAX(PclFechaPrevistaRecepcion) AS
FechaPrevistaRecepcion
FROM dbo.PedidosComprasLineas
GROUP BY IdPedidoCompra
HAVING (IdPedidoCompra B962)



IdPedidoCompra FechaPrevistaRecepcion

(0 filas afectadas)





¿Porqué ocurre esto?

Preguntas similare

Leer las respuestas

#1 Alejandro Mesa
15/01/2008 - 19:50 | Informe spam
Interesante el problema.

Me pregunto por que filtras en la clausula HAVING y no en la clausula WHERE?

SELECT
IdPedidoCompra,
MAX(PclFechaPrevistaRecepcion) AS FechaPrevistaRecepcion
FROM
dbo.PedidosComprasLineas
WHERE
(IdPedidoCompra B962)
GROUP BY
IdPedidoCompra

Puedes mostrarnos el plan de ejecucion de ambos casos, indice con ASC e
indice con DESC?


AMB


"" wrote:

Aunque el problema ya ha sido solucionado, hoy me he encontrado con
una situación que no alcanzo a comprender. No soy un usuario
experimentado de SQL Server, pero no encuentro nada que pueda explicar
el siguiente comportamiento:
Tengo una tabla y deseo saber el el valor máximo de una fecha para
varios registros. Dependiendo de como construya cierto índice, SQL
Server es capaz de localizar el registro. En el primer caso el campo
fecha se ordena ascendente y la instrucción SELECT no devuelve ningún
registro. Si el campo se indexa descendentemente lo encuentra sin
problema. Veamos:


CREATE NONCLUSTERED INDEX
[IX_PedidosComprasLineas_IdPedidoCompra_PclFechaPrevistaRecepcion_] ON
[dbo].[PedidosComprasLineas]
(
[IdPedidoCompra] ASC,
[PclFechaPrevistaRecepcion] DESC

)WITH FILLFACTOR = 90 ON [PRIMARY]



SELECT IdPedidoCompra, MAX(PclFechaPrevistaRecepcion) AS
FechaPrevistaRecepcion
FROM dbo.PedidosComprasLineas
GROUP BY IdPedidoCompra
HAVING (IdPedidoCompra B962)


IdPedidoCompra FechaPrevistaRecepcion
42962 NULL
Advertencia: valor NULL eliminado por el agregado u otra operación
SET.

(1 filas afectadas)





Sin embargo:



CREATE NONCLUSTERED INDEX
[IX_PedidosComprasLineas_IdPedidoCompra_PclFechaPrevistaRecepcion]
ON [dbo].[PedidosComprasLineas]
(
[IdPedidoCompra] ASC,
[PclFechaPrevistaRecepcion] ASC

)WITH FILLFACTOR = 90 ON [PRIMARY]



SELECT IdPedidoCompra, MAX(PclFechaPrevistaRecepcion) AS
FechaPrevistaRecepcion
FROM dbo.PedidosComprasLineas
GROUP BY IdPedidoCompra
HAVING (IdPedidoCompra B962)



IdPedidoCompra FechaPrevistaRecepcion

(0 filas afectadas)





¿Porqué ocurre esto?

Respuesta Responder a este mensaje
#2 xurxof
16/01/2008 - 08:25 | Informe spam
[Nota: ya he cambiado el HAVING por el WHERE]
Primera versión, indice DESC:


StmtText
|--Stream Aggregate(DEFINE:([Expr1002]=MAX([PedidosComprasLineas].
[PclFechaPrevistaRecepcion]), [PedidosComprasLineas].
[IdPedidoCompra]=ANY([PedidosComprasLineas].[IdPedidoCompra])))
|--Index Seek(OBJECT:([Oppida].[dbo].[PedidosComprasLineas].
[IX_PedidosComprasLineas_IdPedidoCompra_PclFechaPrevistaRecepcion]),
SEEK:([PedidosComprasLineas].[IdPedidoCompra]B962) ORDERED FORWARD)



IdPedidoCompra FechaPrevistaRecepcion
42962 NULL
Advertencia: valor NULL eliminado por el agregado u otra operación
SET.




Segunda versión, indice ASC:


StmtText
-
|--Compute Scalar(DEFINE:([PedidosComprasLineas].
[PclFechaPrevistaRecepcion]=[PedidosComprasLineas].
[PclFechaPrevistaRecepcion]))
|--Top(1)
|--Index Seek(OBJECT:([Oppida].[dbo].
[PedidosComprasLineas].
[IX_PedidosComprasLineas_IdPedidoCompra_PclFechaPrevistaRecepcion]),
SEEK:([PedidosComprasLineas].[IdPedidoCompra]B962), WHERE:
([PedidosComprasLineas].[PclFechaPrevistaRecepcion] IS







IdPedidoCompra FechaPrevistaRecepcion


(4 filas afectadas)



Viendo el plan de la segunda versión detecto que el INDEX SEEK incluye
un WHERE IS ... que me llama la atención. El plan detallado muestra la
siguiente linea (el plan detallado completo lo incluyo más abajo):

SEEK:([PedidosComprasLineas].[IdPedidoCompra]B962), WHERE:
([PedidosComprasLineas].[PclFechaPrevistaRecepcion] IS NOT NULL)

Desconozco porqué se incluye esa condición.


On Jan 15, 7:50 pm, Alejandro Mesa
wrote:
Interesante el problema.

Me pregunto por que filtras en la clausula HAVING y no en la clausula WHERE?

SELECT
IdPedidoCompra,
MAX(PclFechaPrevistaRecepcion) AS FechaPrevistaRecepcion
FROM
dbo.PedidosComprasLineas
WHERE
(IdPedidoCompra B962)
GROUP BY
IdPedidoCompra

Puedes mostrarnos el plan de ejecucion de ambos casos, indice con ASC e
indice con DESC?

AMB











Por si es útil, aquí el plan detallado de la primera y la segunda
versión respectivamente:

StmtText
StmtId NodeId Parent PhysicalOp
LogicalOp
Argument
DefinedValues
EstimateRows EstimateIO EstimateCPU AvgRowSize TotalSubtreeCost
OutputList
Warnings Type Parallel EstimateExecutions

-



SELECT IdPedidoCompra, MAX(PclFechaPrevistaRecepcion) AS
FechaPrevistaRecepcion
FROM dbo.PedidosComprasLineas
WHERE IdPedidoCompra B962
GROUP BY IdPedidoCompra 164 1
0 NULL
NULL
1
NULL
1 NULL NULL NULL 0,006410943
NULL
NULL SELECT 0 NULL
|--Stream Aggregate(DEFINE:([Expr1002]=MAX([PedidosComprasLineas].
[PclFechaPrevistaRecepcion]), [PedidosComprasLineas].
[IdPedidoCompra]=ANY([PedidosComprasLineas].
[IdPedidoCompra]))) 164 2
1 Stream Aggregate
Aggregate
NULL
[Expr1002]=MAX([PedidosComprasLineas].[PclFechaPrevistaRecepcion]),
[PedidosComprasLineas].[IdPedidoCompra]=ANY([PedidosComprasLineas].
[IdPedidoCompra]) 1 0 3,277778E-07
15 0,006410943 [PedidosComprasLineas].[IdPedidoCompra],
[Expr1002] NULL
PLAN_ROW 0 1
|--Index Seek(OBJECT:([Oppida].[dbo].[PedidosComprasLineas].
[IX_PedidosComprasLineas_IdPedidoCompra_PclFechaPrevistaRecepcion]),
SEEK:([PedidosComprasLineas].[IdPedidoCompra]B962) ORDERED FORWARD)
164 3 2 Index Seek
Index Seek OBJECT:([Oppida].[dbo].
[PedidosComprasLineas].
[IX_PedidosComprasLineas_IdPedidoCompra_PclFechaPrevistaRecepcion]),
SEEK:([PedidosComprasLineas].[IdPedidoCompra]B962) ORDERED FORWARD
[PedidosComprasLineas].[PclFechaPrevistaRecepcion],
[PedidosComprasLineas].
[IdPedidoCompra]
3,277778 0,0063285 8,211539E-05 37 0,006410616
[PedidosComprasLineas].[PclFechaPrevistaRecepcion],
[PedidosComprasLineas].[IdPedidoCompra] NULL
PLAN_ROW 0 1







StmtText
StmtId NodeId Parent PhysicalOp
LogicalOp
Argument
DefinedValues
EstimateRows EstimateIO EstimateCPU AvgRowSize TotalSubtreeCost
OutputList
Warnings Type Parallel EstimateExecutions
-

-




SELECT IdPedidoCompra, MAX(PclFechaPrevistaRecepcion) AS
FechaPrevistaRecepcion
FROM dbo.PedidosComprasLineas
WHERE IdPedidoCompra B962
GROUP BY
IdPedidoCompra
170 1 0 NULL
NULL
1
NULL
1 NULL NULL NULL 0,006409937
NULL
NULL SELECT 0 NULL
|--Compute Scalar(DEFINE:([PedidosComprasLineas].
[PclFechaPrevistaRecepcion]=[PedidosComprasLineas].
[PclFechaPrevistaRecepcion]))
170 2 1 Compute Scalar
Compute Scalar DEFINE:([PedidosComprasLineas].
[PclFechaPrevistaRecepcion]=[PedidosComprasLineas].
[PclFechaPrevistaRecepcion])
[PedidosComprasLineas].
[PclFechaPrevistaRecepcion]=[PedidosComprasLineas].
[PclFechaPrevistaRecepcion] 1 0 1E-07
15 0,006409937 [PedidosComprasLineas].[IdPedidoCompra],
[PedidosComprasLineas].[PclFechaPrevistaRecepcion] NULL
PLAN_ROW 0 1
|--
Top(1)
170 3 2 Top
Top
NULL
NULL
1 0 1E-07 37 0,006409837
[PedidosComprasLineas].[PclFechaPrevistaRecepcion],
[PedidosComprasLineas].[IdPedidoCompra] NULL
PLAN_ROW 0 1
|--Index Seek(OBJECT:([Oppida].[dbo].
[PedidosComprasLineas].
[IX_PedidosComprasLineas_IdPedidoCompra_PclFechaPrevistaRecepcion]),
SEEK:([PedidosComprasLineas].[IdPedidoCompra]B962), WHERE:
([PedidosComprasLineas].[PclFechaPrevistaRecepcion] IS 170
4 3 Index Seek Index
Seek OBJECT:([Oppida].[dbo].[PedidosComprasLineas].
[IX_PedidosComprasLineas_IdPedidoCompra_PclFechaPrevistaRecepcion]),
SEEK:([PedidosComprasLineas].[IdPedidoCompra]B962), WHERE:
([PedidosComprasLineas].[PclFechaPrevistaRecepcion] IS NOT NULL)
ORDERED BACKWAR [PedidosComprasLineas].[PclFechaPrevistaRecepcion],
[PedidosComprasLineas].[IdPedidoCompra], [KeyCo1] 1
0,00316425 4,105769E-05 37 0,006409036
[PedidosComprasLineas].[PclFechaPrevistaRecepcion],
[PedidosComprasLineas].[IdPedidoCompra], [KeyCo1] NULL
PLAN_ROW 0 1
Respuesta Responder a este mensaje
#3 Jesús López
16/01/2008 - 10:05 | Informe spam
Eso suena a bug de SQL Server. En ningún caso los índices deben influir en
el resultado de las consultas, sólo en el tiempo que tardan en ejecutarse.

¿Qué versión y service pack tienes?

¿Has informado a MS de esto?

Jesús López
www.solidq.com



escribió en el mensaje
news:
Aunque el problema ya ha sido solucionado, hoy me he encontrado con
una situación que no alcanzo a comprender. No soy un usuario
experimentado de SQL Server, pero no encuentro nada que pueda explicar
el siguiente comportamiento:
Tengo una tabla y deseo saber el el valor máximo de una fecha para
varios registros. Dependiendo de como construya cierto índice, SQL
Server es capaz de localizar el registro. En el primer caso el campo
fecha se ordena ascendente y la instrucción SELECT no devuelve ningún
registro. Si el campo se indexa descendentemente lo encuentra sin
problema. Veamos:


CREATE NONCLUSTERED INDEX
[IX_PedidosComprasLineas_IdPedidoCompra_PclFechaPrevistaRecepcion_] ON
[dbo].[PedidosComprasLineas]
(
[IdPedidoCompra] ASC,
[PclFechaPrevistaRecepcion] DESC

)WITH FILLFACTOR = 90 ON [PRIMARY]



SELECT IdPedidoCompra, MAX(PclFechaPrevistaRecepcion) AS
FechaPrevistaRecepcion
FROM dbo.PedidosComprasLineas
GROUP BY IdPedidoCompra
HAVING (IdPedidoCompra B962)


IdPedidoCompra FechaPrevistaRecepcion
42962 NULL
Advertencia: valor NULL eliminado por el agregado u otra operación
SET.

(1 filas afectadas)





Sin embargo:



CREATE NONCLUSTERED INDEX
[IX_PedidosComprasLineas_IdPedidoCompra_PclFechaPrevistaRecepcion]
ON [dbo].[PedidosComprasLineas]
(
[IdPedidoCompra] ASC,
[PclFechaPrevistaRecepcion] ASC

)WITH FILLFACTOR = 90 ON [PRIMARY]



SELECT IdPedidoCompra, MAX(PclFechaPrevistaRecepcion) AS
FechaPrevistaRecepcion
FROM dbo.PedidosComprasLineas
GROUP BY IdPedidoCompra
HAVING (IdPedidoCompra B962)



IdPedidoCompra FechaPrevistaRecepcion

(0 filas afectadas)





¿Porqué ocurre esto?
Respuesta Responder a este mensaje
#4 xurxof
16/01/2008 - 12:34 | Informe spam
On Jan 16, 10:05 am, "Jesús López"
wrote:
Eso suena a bug de SQL Server. En ningún caso los índices deben influir en
el resultado de las consultas, sólo en el tiempo que tardan en ejecutarse.

¿Qué versión y service pack tienes?

¿Has informado a MS de esto?

Jesús Lópezwww.solidq.com





Me temo que tienes razón: el servidor no tiene el último service pack
4 instalado. Lo actualizaré esta noche. En caso de que ésto no se
corrija el problema, volveré a solicitar informacón.
Gracias.
Respuesta Responder a este mensaje
#5 xurxof
18/01/2008 - 08:36 | Informe spam
On Jan 16, 12:34 pm, wrote:

Me temo que tienes razón: el servidor no tiene el último service pack
4 instalado. Lo actualizaré esta noche. En caso de que ésto no se
corrija el problema, volveré a solicitar informacón.
Gracias.




Bueno, una vez actualizado a SQL Server 2000 SP4 la misma consulta
obtiene los mismos resultados independientemente del orden de la
indexación. Sin embargo, descubro que las condiciones son similares.


SELECT IdPedidoCompra, MAX(PclFechaPrevistaRecepcion) AS
FechaPrevistaRecepcion
FROM dbo.PedidosComprasLineas
WHERE IdPedidoCompra B961
GROUP BY IdPedidoCompra
GO


IdPedidoCompra FechaPrevistaRecepcion



SELECT IdPedidoCompra, MAX(PclFechaPrevistaRecepcion) AS
FechaPrevistaRecepcion
FROM dbo.PedidosComprasLineas
WHERE IdPedidoCompra >42960 and IdPedidoCompra <42962
GROUP BY IdPedidoCompra
GO



IdPedidoCompra FechaPrevistaRecepcion
42961 NULL
Advertencia: valor NULL eliminado por el agregado u otra operación
SET.



Es esto normal? Gracias por la paciencia.
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida