Internal SQL Server Error

07/11/2006 - 15:03 por jcac | Informe spam
Hola lista tebgo un problema armando este query:

Select D.PROD_CodProd, Max(V.VALE_FecEmi),
(Select D1.DVAL_CostoPS From DetValesAlm D1 Inner Join Vales V1 On
D1.SUCR_Codigo = V1.SUCR_Codigo And D1.ALMA_Codigo = V1.ALMA_Codigo And
D1.TIPO_CodVale = V1.TIPO_CodVale And D1.VALE_NumVale = V1.VALE_NumVale
Where D.SUCR_Codigo = D1.SUCR_Codigo And D.ALMA_Codigo = D1.ALMA_Codigo
And D.TIPO_CodVale = D1.TIPO_CodVale And D.VALE_NumVale = D1.VALE_NumVale
And D.PROD_CodProd = D1.PROD_CodProd And Max(V.VALE_FecEmi) =
V1.VALE_FecEmi) As XX
From DetValesAlm D Inner Join Vales V On D.SUCR_Codigo = V.SUCR_Codigo And
D.ALMA_Codigo = V.ALMA_Codigo And D.TIPO_CodVale = V.TIPO_CodVale And
D.VALE_NumVale = V.VALE_NumVale
Where D.PROD_CodProd = '2130080001' And V.VALE_Estado = 'C' And
Month(V.VALE_FecEmi) = 9 And Year(V.VALE_FecEmi) = 2006
Group by D.PROD_CodProd


Cuando lo ejecute de esta manera no me pasa nada:

Select D.PROD_CodProd, Max(V.VALE_FecEmi)
From DetValesAlm D Inner Join Vales V On D.SUCR_Codigo = V.SUCR_Codigo And
D.ALMA_Codigo = V.ALMA_Codigo And D.TIPO_CodVale = V.TIPO_CodVale And
D.VALE_NumVale = V.VALE_NumVale
Where D.PROD_CodProd = '2130080001' And V.VALE_Estado = 'C' And
Month(V.VALE_FecEmi) = 9 And Year(V.VALE_FecEmi) = 2006
Group by D.PROD_CodProd

Ya que aqui consiguo el producto con su maxima fecha en un mes especifico,
sin embargo cuando deseo sacar su costo de ese producto lo hago haciendo el
primer query que le he puesto y me da el error del Asunto

Mi SQL Server es 2000 Standart con SP4 y corre bajo un Windows 2000 Server
SP4

Saludos y gracias por su tiempo

Preguntas similare

Leer las respuestas

#11 jcac
07/11/2006 - 23:27 | Informe spam
Gracias Alejandro,

He visto lo que me comentas en tu ejemplo y definitivamente tienes que andar
viendo siempre tus planes de ejecución, para determinar cual es la mejor
opción.

Te agradesco la literatura que me haz dado para leer, tengo mucho por leer y
aprender y luego aplicar.

Muchas gracias

Saludos




"Alejandro Mesa" escribió en el
mensaje news:
jcac,

Dame un par de dias para digerir toda esta informacion y te comento
respecto
a los indices actuales y lo que el plan de ejecucion esta haciendo.

Solo como una consulta más, como sabes que manipular columnas en el where
no
es bueno, por que por lo menos eso no lo dicen en ningún sitio o es que
con
los planes de ejecución es suficiente para uno darse cuenta de ello, ya
que
en varios querys que hay en este sistema hay varias consultas que
realizan
de esta manera Campo = IsNull(@Campo, Campo) y lei el comentario de que
no
era bueno. Si me pudieras indicar una buena bibliografia donde puedo
encontrar todos estos temas de rendimiento mas que todo y como hacer que
el
Sql Server trabaje de la mejor manera.



Para que SQL Server considere una expresion como un argumento de busqueda,
lo primero es que la columna no se manipule, puesto que si existe un
indice
(como por ejemplo por la columna [VALE_FecEmi]) la distribucion de valores
en
esa columna esta calculado en base al valor en si y no al resultado de
aplicar una funcion y/o transformacion a la columna. Recuerda que SQL
Server
usa las estadisticas de distribucion de los indices para estimar cuantas
filas tendra el resultado y en base a eso (tambien a otros parametros)
escojera que tipo de operacion realizar. Si el valor de la expresion no
puede
ser usado para buscar en las estadisticas, entonces SQL Server no hara el
intento de usar ese indice, al menos no de forma optima. La forma de la
expresion debe ser:

<columna> <operador> <variable o constante>
<variable o constante> <operador> <columna>

Veamos un ejemplo concreto:

use northwind
go

set showplan_text on
go

declare @orderid int

set @orderid = null

select
*
from
dbo.orders
where
orderid = isnull(@orderid, orderid)

select
*
from
dbo.orders
where
orderid between coalesce(@orderid, convert(int, 0x80000000)) and
coalesce(@orderid, convert(int, 0x7FFFFFFF))
go

set showplan_text off
go

Planes de ejecucion estimados:

Query - 1

|--Nested Loops(Inner Join, OUTER
REFERENCES:([northwind].[dbo].[Orders].[OrderID]))
|--Index Scan(OBJECT:([northwind].[dbo].[Orders].[EmployeeID]),
WHERE:([northwind].[dbo].[Orders].[OrderID]=isnull([@orderid],[northwind].[dbo].[Orders].[OrderID])))
|--Clustered Index
Seek(OBJECT:([northwind].[dbo].[Orders].[PK_Orders]),
SEEK:([northwind].[dbo].[Orders].[OrderID]=[northwind].[dbo].[Orders].[OrderID])
LOOKUP ORDERED FORWARD)

Query - 2

|--Clustered Index Seek(OBJECT:([northwind].[dbo].[Orders].[PK_Orders]),
SEEK:([northwind].[dbo].[Orders].[OrderID] >= CASE WHEN [@orderid] IS NOT
NULL THEN [@orderid] ELSE (-2147483648) END AND
[northwind].[dbo].[Orders].[OrderID] <= CASE WHEN [@orderid] IS NOT NULL
THEN
[@orderid] ELSE (2147483647) END) ORDERED FORWARD)

Costos estimados:

query 1 - 68%
query 2 - 32%

Como vez, la segunda sentencia tiene menos costo asociado porque SQL
Server
escojio hacer un "index seek" en el indice pk_orders. Fijate en el plan de
la
primera sentencia, que te parece ese plan?, horrible.

Te paso unos cuantos links para que leas al respecto.

INF: Los argumentos de búsqueda que determinan distribución paginan uso
http://support.microsoft.com/kb/169642/es

Ajuste y optimización del rendimiento de MS SQL Server para programadores,
primera parte: Introducción a los aspectos de rendimiento
http://www.microsoft.com/latam/tech...005/art02/

Estadísticas de distribución en SQL Server 2000 (I)
http://www.helpdna.net/colab02.htm

Estadísticas de Distribución en SQL Server 2000 (2)
http://www.configuracionesintegrale...articulo35

Estadísticas utilizadas por el optimizador de consultas de Microsoft SQL
Server 2000
http://www.microsoft.com/spanish/ms...tquery.asp

Ajuste del rendimiento de las consultas (SQL Server Mobile)
http://msdn2.microsoft.com/es-es/li...72984.aspx


AMB


"jcac" wrote:

Hola Alejandro

Gracias, si creo que todos llegamos aqui para que quizás nos den una
solución, por ello mismo es que te agradesco tu disposición por ayudar y
por
tu tiempo que pienso que a todos nos cuesta.

Te paso los indices y restricciones que hay en esa tabla, de por lo menos
los campos que intervenienenj

index_name index_description
index_keys
IX_DetValesAlm nonclustered located on PRIMARY
SUCR_Codigo, ALMA_Codigo, TIPO_TabVale, TIPO_CodVale, VALE_NumVale
PK__DetValesAlm__075714DC nonclustered, unique, primary key located on
PRIMARY ALMA_Codigo, SUCR_Codigo, VALE_NumVale, DVAL_Item, TIPO_TabVale,
TIPO_CodVale

No tiene otro indice adicional, es una aplicación de terceros, que como
alguien dijo por alli no recuerdo quien, comento que solo lo programan
pero
no hacen pruebas como para saber que es mejor para la base solo con que
funcione ya esta hecho asi no sea lo mejor.

Por ello con uds. en este foro he aprendido mucho aunque como dicen a
golpes
pero lo he hecho y mi prespectiva con respecto de ver al SQL Server a
cambiado.

Te adjunto el plan de ejecución del query que me pasaste.

Select D.PROD_CodProd, V.VALE_FecEmi, D.DVAL_CostoPS From DetValesAlm D
Inner Join Vales V On D.SUCR_Codigo = V.SUCR_Codigo And D.ALMA_Codigo
>> V.ALMA_Codigo And D.TIPO_CodVale = V.TIPO_CodVale And D.VALE_NumVale >> V.VALE_NumVale -- Where D.PROD_CodProd = '2130080001' And V.VALE_Estado
>> 'C' And Month(V.VALE_FecEmi) = 9 And Year(V.VALE_FecEmi) = 2006 Where
D.PROD_CodProd = '2130080001' And V.VALE_Estado = 'C' And V.VALE_FecEmi
>>> '20060901' and V.VALE_FecEmi < '20061001' And V.VALE_FecEmi = (Select
Max(V1.VALE_FecEmi) From DetValesAlm D1 Inner Join Vales V1 On
D1.SUCR_Codigo = V1.SUCR_Codigo And D1.ALMA_Codigo = V1.ALMA_Codigo And
D1.TIPO_CodVale = V1.TIPO_CodVale And D1.VALE_NumVale = V1.VALE_NumVale
Where D1.PROD_CodProd = D.PROD_CodProd And V1.VALE_Estado = V.VALE_Estado
And V1.VALE_FecEmi >= '20060901' and V1.VALE_FecEmi < '20061001')
|--Nested Loops(Inner Join, OUTER REFERENCES:([D].[VALE_NumVale],
[D].[TIPO_CodVale], [D].[ALMA_Codigo], [D].[SUCR_Codigo],
[V1].[VALE_Estado], [Expr1004]) WITH PREFETCH)
|--Hash Match(Aggregate, HASH:([Rank1007], [V1].[VALE_Estado]),
RESIDUAL:([Rank1007]=[Rank1007] AND
[V1].[VALE_Estado]=[V1].[VALE_Estado])
DEFINE:([Expr1004]=MAX([V1].[VALE_FecEmi]),
[D].[VALE_NumVale]=ANY([D].[VALE_NumVale]),
[D].[TIPO_CodVale]=ANY([D].[TIPO_CodVale]),
[D].[ALMA_Codigo]=ANY([D].[ALMA_Codigo]),
[D].[SUCR_Codigo]=ANY([D].[SUCR_Codigo]),
[D].[DVAL_CostoPS]=ANY([D].[DVAL_CostoPS]),
[D].[PROD_CodProd]=ANY([D].[PROD_CodProd])))
| |--Hash Match(Inner Join, HASH:([D1].[SUCR_Codigo],
[D1].[ALMA_Codigo], [D1].[TIPO_CodVale],
[D1].[VALE_NumVale])=([V1].[SUCR_Codigo], [V1].[ALMA_Codigo],
[V1].[TIPO_CodVale], [V1].[VALE_NumVale]),
RESIDUAL:((([V1].[SUCR_Codigo]=[D1].[SUCR_Codigo] AND
[V1].[ALMA_Codigo]=[D1].[ALMA_Codigo]) AND
[V1].[TIPO_CodVale]=[D1].[TIPO_CodVale]) AND
[V1].[VALE_NumVale]=[D1].[VALE_NumVale]))
| |--Hash Match(Inner Join,
HASH:([D].[PROD_CodProd])=([D1].[PROD_CodProd]),
RESIDUAL:([D1].[PROD_CodProd]=[D].[PROD_CodProd]))
| | |--Rank
| | | |--Table
Scan(OBJECT:([Layconsa].[dbo].[DetValesAlm] AS [D]),
WHERE:([D].[PROD_CodProd]='2130080001'))
| | |--Table
Scan(OBJECT:([Layconsa].[dbo].[DetValesAlm]
AS [D1]))
| |--Clustered Index
Scan(OBJECT:([Layconsa].[dbo].[Vales].[PK__Vales__1EB046D7] AS [V1]),
WHERE:([V1].[VALE_FecEmi]>='Sep 1 2006 12:00AM' AND
[V1].[VALE_FecEmi]<'Oct
1 2006 12:00AM'))
|--Clustered Index
Seek(OBJECT:([Layconsa].[dbo].[Vales].[PK__Vales__1EB046D7] AS [V]),
SEEK:([V].[VALE_NumVale]=[D].[VALE_NumVale]),
WHERE:((((((([V].[VALE_FecEmi]=[Expr1004] AND [V].[VALE_FecEmi]>='Sep 1
2006 12:00AM') AND [V].[VALE_FecEmi]<'Oct 1 2006 12:00AM') AND
[V1].[VALE_Estado]=[V].[VALE_Estado]) AND
[V].[SUCR_Codigo]=[D].[SUCR_Codigo]) AND
[V].[ALMA_Codigo]=[D].[ALMA_Codigo]) AND
[V].[TIPO_CodVale]=[D].[TIPO_CodVale]) AND [V].[VALE_Estado]='C') ORDERED
FORWARD)

Aqui te pongo el plan de ejecución del query que te he utilizado
finalmente

Select Top 1 D.PROD_CodProd, D.DVAL_CostoPS, V.VALE_FecEmi From Vales V
Inner Join DetValesAlm D On V.SUCR_Codigo = D.SUCR_Codigo And
V.ALMA_Codigo
= D.ALMA_Codigo And V.TIPO_TabVale = D.TIPO_TabVale And V.TIPO_CodVale >> D.TIPO_CodVale And V.VALE_NumVale = D.VALE_NumVale Where V.VALE_Estado >> 'C' And Month(V.VALE_FecEmi) = 9 And Year(V.VALE_FecEmi) = 2006 And
D.PROD_CodProd = '2130080001' Order By V.VALE_FecEmi Desc
|--Top(1)
|--Filter(WHERE:([D].[PROD_CodProd]='2130080001'))
|--Bookmark Lookup(BOOKMARK:([Bmk1001]),
OBJECT:([Layconsa].[dbo].[DetValesAlm] AS [D]))
|--Nested Loops(Inner Join, OUTER
REFERENCES:([V].[VALE_NumVale], [V].[TIPO_CodVale], [V].[TIPO_TabVale],
[V].[ALMA_Codigo], [V].[SUCR_Codigo]) WITH PREFETCH)
|--Sort(ORDER BY:([V].[VALE_FecEmi] DESC))
| |--Clustered Index
Scan(OBJECT:([Layconsa].[dbo].[Vales].[PK__Vales__1EB046D7] AS [V]),
WHERE:(([V].[VALE_Estado]='C' AND datepart(month, [V].[VALE_FecEmi])=9)
AND
datepart(year, [V].[VALE_FecEmi]) 06))
|--Index
Seek(OBJECT:([Layconsa].[dbo].[DetValesAlm].[IX_DetValesAlm] AS [D]),
SEEK:([D].[SUCR_Codigo]=[V].[SUCR_Codigo] AND
[D].[ALMA_Codigo]=[V].[ALMA_Codigo] AND
[D].[TIPO_TabVale]=[V].[TIPO_TabVale] AND
[D].[TIPO_CodVale]=[V].[TIPO_CodVale] AND
[D].[VALE_NumVale]=[V].[VALE_NumVale]) ORDERED FORWARD)

Gracias Alejandro una ves más.

Solo como una consulta más, como sabes que manipular columnas en el where
no
es bueno, por que por lo menos eso no lo dicen en ningún sitio o es que
con
los planes de ejecución es suficiente para uno darse cuenta de ello, ya
que
en varios querys que hay en este sistema hay varias consultas que
realizan
de esta manera Campo = IsNull(@Campo, Campo) y lei el comentario de que
no
era bueno. Si me pudieras indicar una buena bibliografia donde puedo
encontrar todos estos temas de rendimiento mas que todo y como hacer que
el
Sql Server trabaje de la mejor manera.

Saludos


"Alejandro Mesa" escribió en el
mensaje news:
> jcac,
>
> Nadie mejor que tu conoce tu aplicacion, asi que cualquier cambio o
> solucion
> que venga de ti es incuestionable. una sugerencia, no manipules las
> columnas
> en la clausula "where", esto evita que sql server pueda hacer un uso
> adecuado
> de los indices.
>
>> Month(V.VALE_FecEmi) = 9 And Year(V.VALE_FecEmi) = 2006
>
> V.VALE_FecEmi >= '20060901' and V.VALE_FecEmi < '20061001'
>
>> resultado del mes, además que segun el plan de ejecucion se demora
>> demasiado
>> cerca de 47 segun y realiza dos table scan, pensandolo de otra forma
>> lo
>> hice
>
> Me pregunto cuales son los indices de esas tablas, restricciones de
> clave
> foranea, de unicidad, etc.?
>
>
> AMB
>
> "jcac" wrote:
>
>> Hola Alejandro
>>
>> Si el query me diste funciona pero segun mis datos que hay cambios de
>> costo
>> dentro del mismo mes, me vota distintos resultados, y solo queria el
>> ultimo
>> resultado del mes, además que segun el plan de ejecucion se demora
>> demasiado
>> cerca de 47 segun y realiza dos table scan, pensandolo de otra forma
>> lo
>> hice
>> asi:
>>
>> Select Top 1 D.PROD_CodProd, D.DVAL_CostoPS, V.VALE_FecEmi
>> From Vales V Inner Join DetValesAlm D On V.SUCR_Codigo = D.SUCR_Codigo
>> And
>> V.ALMA_Codigo = D.ALMA_Codigo And V.TIPO_TabVale = D.TIPO_TabVale And
>> V.TIPO_CodVale = D.TIPO_CodVale And V.VALE_NumVale = D.VALE_NumVale
>> Where V.VALE_Estado = 'C' And Month(V.VALE_FecEmi) = 9 And
>> Year(V.VALE_FecEmi) = 2006 And D.PROD_CodProd = '2130080001'
>> Order By V.VALE_FecEmi Desc
>>
>> Gracias por tu tiempo y disposición a ayudar y colaborar en el foro
>>
>> Saludos
>>
>> PD. Uno siempre aprende algo más de todos UDs.
>>
>> PD1. Si bien la respuesta es para Alejandro les agradesco a todos por
>> su
>> tiempo
>>
>> "Alejandro Mesa" escribió en
>> el
>> mensaje news:
>> > Correccion:
>> >
>> > Select
>> > D.PROD_CodProd,
>> > V.VALE_FecEmi,
>> > D.DVAL_CostoPS
>> > From
>> > DetValesAlm D
>> > Inner Join
>> > Vales V
>> > On D.SUCR_Codigo = V.SUCR_Codigo
>> > And D.ALMA_Codigo = V.ALMA_Codigo
>> > And D.TIPO_CodVale = V.TIPO_CodVale
>> > And D.VALE_NumVale = V.VALE_NumVale
>> > Where
>> > D.PROD_CodProd = '2130080001'
>> > And V.VALE_Estado = 'C'
>> > And V.VALE_FecEmi = (
>> > Select
>> > Max(V1.VALE_FecEmi)
>> > From
>> > DetValesAlm D 1
>> > Inner Join
>> > Vales V1
>> > On D1.SUCR_Codigo = V1.SUCR_Codigo
>> > And D1.ALMA_Codigo = V1.ALMA_Codigo
>> > And D1.TIPO_CodVale = V1.TIPO_CodVale
>> > And D1.VALE_NumVale = V1.VALE_NumVale
>> > Where
>> > D1.PROD_CodProd = D.PROD_CodProd
>> > And V1.VALE_Estado = V.VALE_Estado
>> > and V1.VALE_FecEmi >= '20060901' and V1.VALE_FecEmi < '20061001'
>> > )
>> > go
>> >
>> >
>> > AMB
>> >
>> > "Alejandro Mesa" wrote:
>> >
>> >> Trata:
>> >>
>> >> Select
>> >> D.PROD_CodProd,
>> >> V.VALE_FecEmi,
>> >> D.DVAL_CostoPS
>> >> From
>> >> DetValesAlm D
>> >> Inner Join
>> >> Vales V
>> >> On D.SUCR_Codigo = V.SUCR_Codigo
>> >> And D.ALMA_Codigo = V.ALMA_Codigo
>> >> And D.TIPO_CodVale = V.TIPO_CodVale
>> >> And D.VALE_NumVale = V.VALE_NumVale
>> >> Where
>> >> D.PROD_CodProd = '2130080001'
>> >> And V.VALE_Estado = 'C'
>> >> And V.VALE_FecEmi = (
>> >> Select
>> >> Max(V.VALE_FecEmi)
>> >> From
>> >> DetValesAlm D 1
>> >> Inner Join
>> >> Vales V1
>> >> On D1.SUCR_Codigo = V1.SUCR_Codigo
>> >> And D1.ALMA_Codigo = V1.ALMA_Codigo
>> >> And D1.TIPO_CodVale = V1.TIPO_CodVale
>> >> And D1.VALE_NumVale = V1.VALE_NumVale
>> >> Where
>> >> D1.PROD_CodProd = D.PROD_CodProd
>> >> And V1.VALE_Estado = V.VALE_Estado
>> >> and V1.VALE_FecEmi >= '20060901' and V1.VALE_FecEmi < '20061001'
>> >> )
>> >> go
>> >>
>> >>
>> >> AMB
>> >>
>> >>
>> >> "jcac" wrote:
>> >>
>> >> > Hola lista tebgo un problema armando este query:
>> >> >
>> >> > Select D.PROD_CodProd, Max(V.VALE_FecEmi),
>> >> > (Select D1.DVAL_CostoPS From DetValesAlm D1 Inner Join Vales V1
>> >> > On
>> >> > D1.SUCR_Codigo = V1.SUCR_Codigo And D1.ALMA_Codigo =
>> >> > V1.ALMA_Codigo
>> >> > And
>> >> > D1.TIPO_CodVale = V1.TIPO_CodVale And D1.VALE_NumVale >> >> >> > V1.VALE_NumVale
>> >> > Where D.SUCR_Codigo = D1.SUCR_Codigo And D.ALMA_Codigo >> >> >> > D1.ALMA_Codigo
>> >> > And D.TIPO_CodVale = D1.TIPO_CodVale And D.VALE_NumVale >> >> >> > D1.VALE_NumVale
>> >> > And D.PROD_CodProd = D1.PROD_CodProd And Max(V.VALE_FecEmi) >> >> >> > V1.VALE_FecEmi) As XX
>> >> > From DetValesAlm D Inner Join Vales V On D.SUCR_Codigo >> >> >> > V.SUCR_Codigo
>> >> > And
>> >> > D.ALMA_Codigo = V.ALMA_Codigo And D.TIPO_CodVale = V.TIPO_CodVale
>> >> > And
>> >> > D.VALE_NumVale = V.VALE_NumVale
>> >> > Where D.PROD_CodProd = '2130080001' And V.VALE_Estado = 'C' And
>> >> > Month(V.VALE_FecEmi) = 9 And Year(V.VALE_FecEmi) = 2006
>> >> > Group by D.PROD_CodProd
>> >> >
>> >> >
>> >> > Cuando lo ejecute de esta manera no me pasa nada:
>> >> >
>> >> > Select D.PROD_CodProd, Max(V.VALE_FecEmi)
>> >> > From DetValesAlm D Inner Join Vales V On D.SUCR_Codigo >> >> >> > V.SUCR_Codigo
>> >> > And
>> >> > D.ALMA_Codigo = V.ALMA_Codigo And D.TIPO_CodVale = V.TIPO_CodVale
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida