Sql 2005 MultiHilo o hyperthreading o Dual Core

27/07/2006 - 10:52 por GenioMaestro | Informe spam
Hola a todos:

Tengo una aplicación desarrollada en sql 2005 que entrará en produccion en
septiembre, espero, y tengo algunos problemas que me hacen dudar sobre la
configuracion de la maquina de produccion.

Es un sistema de calculo bursatil. La base de datos tiene ya unos 15 GB y
creciendo. La estructura interna es muy sencilla, tan solo tengo dos tablas
principales, una de cotizaciones con 8 campos y otra de calculos con 53
campos. Pero eso si, cada tabla tiene unos 25 Millones de registros.

El programa lo he desarrollado en el portatil, un centrino 1.6 con 1 Gb de
memoria y se mueve muy bien, usando el micro siempre por encima del 80% y
mucho tiempo al 100%, lo que veo normal porque estoy haciendo muchos
calculos matematicos y consultas bastante complejas.

El problema lo tengo al pasar a la maquina grande de desarrollo. Es un
Pentium4 3.2 con HT, un 630 o 640 con 2 Gb de memoria y 200 Gb de disco duro
Sata2 de 3 Gbs y NCQ. En esta maquina, el uso del procesador está cerca del
50% con un máximo del 55%. Parece como si no usara el HT. Y sin embargo, los
dos graficos se mueven en paralelo, cuando uno sube el otro baja y
viceversa.

En el portatil centrino no hay HT y supuse que al pasarlo a la maquina
grande, con un micro más potente, los tiempos mejorarían, pero no es así. He
probado a poner un Dual Core, que no es HT, pero me pasa lo mismo. Los
tiempos de calculo son exactamente los mismos, tanto en el portatil como en
el P4 con HT que con el Dual Core.

Alguna idea de lo que puede estar pasando???? Que maquina pongo en
produccion si todas las maquinas me tardan lo mismo????

Todas las maquinas tienen Windows XP Pro SP2, y la version demo de 6 meses
de Sql Server 2005 Enterprise.

Espero vuestras ideas y orientaciones.

Gracias.

Preguntas similare

Leer las respuestas

#11 GenioMaestro
28/07/2006 - 21:55 | Informe spam
Que descripcion necesitas??? No entiendo que quieres decir con uno o dos
niveles.

Y que parte del scrip de base de datos???


"Miguel Egea" escribió en el mensaje
news:
Creo que puede mejorarse, vamos a ver como, ¿nos pasas una descripcion de
uno o dos niveles del tema de cotizaciones yh el script?

Saludos
Miguel Egea
"GenioMaestro" wrote in message
news:
Puedo poner set statitisc io on y set statistics time on en el
administrador corporativo, lanzando una consulta o un procedimiento
almacenado y deciros lo que da, pero todas las consultas y funciones han
sido depuradas al limite. Os paso una de las operaciones mas pesadas.

update calculos set
Max_Nivel1 = ...,
Max_Nivel2 = ...,
Max_Nivel3 = ...,
Max_Nivel4 = ...,
Max_Nivel5 = ( select top 1 cierre from (SELECT TOP 2 cierre FROM (
SELECT TOP 1900 CIERRE FROM COTIZACIONES WITH (TABLOCKX)
WHERE COD_VALOR = @PASA_VALOR AND FECHA < (SELECT TOP 1 FECHA FROM
(SELECT TOP 600 FECHA FROM COTIZACIONES WITH (TABLOCKX) WHERE COD_VALOR
= @PASA_VALOR AND FECHA <= FECHA_CAL ORDER BY FECHA DESC) AS XX_TEMPO
ORDER BY FECHA ASC)
ORDER BY FECHA DESC) AS XX_TEMPO ORDER BY CIERRE DESC ) as xx_tempo2
order by cierre asc ) ,
Min_Nivel1 = ...,
Min_Nivel2 = ...,
Min_Nivel3 = ...,
Min_Nivel4 = ...,
Min_Nivel5 = ( select top 1 cierre from (SELECT TOP 2 cierre FROM (
SELECT TOP 1900 CIERRE FROM COTIZACIONES WITH (TABLOCKX)
WHERE COD_VALOR = @PASA_VALOR AND FECHA < (SELECT TOP 1 FECHA FROM
(SELECT TOP 600 FECHA FROM COTIZACIONES WITH (TABLOCKX) WHERE COD_VALOR
= @PASA_VALOR AND FECHA <= FECHA_CAL ORDER BY FECHA DESC) AS XX_TEMPO
ORDER BY FECHA ASC)
ORDER BY FECHA DESC) AS XX_TEMPO ORDER BY CIERRE ASC ) as xx_tempo2 order
by cierre DESC )
FROM CALCULOS WITH (TABLOCKX)
where cod_valor = @PASA_VALOR
and FECHA_CAL >= @F_INI and FECHA_CAL < @F_FIN

Es un SELECT de SELECT de SELECT WHERE SUBSELECT de SUBSELECT, son 5
anidaciones. Es la septima version y hasta el momento es la más rapida
que conseguido. Empeze con un cursor que era terriblemente lento, luego
con WHERE fecha NOT IN (SELECT ...) y tambien era muy lento. Ademas
averigue que si lo calculaba desde una funcion de usuario UDF era más
lento que si lanzaba la consulta directamente en la clausula update, osea
que quite las funciones. Luego probe con optimizaciones como WITH
(TABLOCKX) y la cosa mejoro mucho. Esto es lo mas optimizado que he
conseguido. Puntualizo que aun quitando las optimizaciones WITH
(TABLOCKX) el micro HT hace lo mismo, pero tardando mas tiempo.

Los niveles 1,2,3 y 4 se calculan de la misma forma pero con otros rangos
TOP. Para averiguar el maximo se ordena en ascendente y para el mínimo en
descendente, por lo demas las consultas son identicas. En el nivel 5
necesito procesar 2500 registros, 1900 + 600 = 2500, que multiplicado por
los 10.000 valores da la friolera de 25 millones de registros. Por tanto,
cada vez que calculo todos los valores de todos los mercados, la fase 1
donde esta este update, se pasea por todos y cada uno de los registros de
cotizaciones.

El problema esta en que cuando pasemos a produccion, el cliente quiere
tener de 30.000 a 50.000 valores, lo que me da de 75 a 125 millones de
registros. Creo que voy a tener que particionar las tablas y los indices,
aunque el problema no es de disco duro, la cola de disco esta siempre en
cero con un maximo de 2.

Me extraña mucho que este proceso no sea paralelizable, solo son dos
select pesados, uno de 600 registros y otro de 1900, las otras tres
consultas solo sacan 1 registro o 2, una nimiedad para sql server, y
segun estoy escribiendo se me esta ocurriendo algo. Voy a probar y os
cuento.



"Miguel Egea" escribió en el mensaje
news:
de los que me parecen significativos las esperas tienes de dos tipos
pagelatch y pageiolatch una es contención de caché , la otra es
contención de disco, ninguna creo que sea especialmente significativa ni
que tenga que ver con tu proceso. Lo que si que podemos hacer es
optimización pura y dura

Si puedes ejecutar tu proceso poniento set statitisc io on, set
statistics time on después ejecutar tu proceso y pasarnos los resultados
podemos seguir mirando, No es que SQL sea una aplicacio´n indicada para
hacer "calculo vectorial", pero no creo que en operaciones "pequeñas" de
cpu te vaya a suponer un cuello de botella, tiene que haber algo más.

Saludos
Miguel Egea


"GenioMaestro" wrote in message
news:%
Me dice esto:

Total 89835 571562 578
SOS_SCHEDULER_YIELD 58124 312 296
PAGELATCH_EX 24534 93 78
SLEEP_BPOOL_FLUSH 3214 19109 140
WRITELOG 2467 2265 62
PAGEIOLATCH_SH 422 9796 0
PAGEIOLATCH_EX 380 4265 0
LAZYWRITER_SLEEP 269 267625 0
SLEEP_TASK 234 0 0
ASYNC_NETWORK_IO 115 31 0
SQLTRACE_BUFFER_FLUSH 67 268000 0
PAGEIOLATCH_UP 9 62 0


La fila de CXPACKET da cero en las tres columnas. Por tanto mi problema
no es por las esperas CXPACKET.

Creo que el problema es otro. No se exactamente donde lo he leido, pero
creo que lo unico que se puede paralelizar son las SELECT, no los
INSERT, ni los UPDATE, ni los DELETE.

Precisamente, el sistema de calculo lo que hace es, primero un INSERT
en la tabla calculos, y luego varios UPDATE en la misma tabla.

Lo que tengo es un registro en la tabla de calculos por cada registro
en la tabla de cotizaciones. Y luego calculo muchas cosas
interdependientes, es decir, algunos calculos se hacen mediante select
sobre la tabla de cotizaciones, pero otros se hacen con select de la
tabla calculos. Más claro. Las columnas 1 a 7 de la tabla calculos las
obtengo con una select sobre la tabla cotizaciones, pero para calcular
las columnas 8 a 11 necesito datos de las columnas 1 a 7 de la tabla de
calculos.

Creo el sistema de calculo no corre más porque no puede correr más. Si
desactivo el HT en el equipo grande, el uso de micro se mueve
exactamente igual que en el portatil, y los tiempos son ligeramente
inferiores, de 3.8 seg que tarda en el portatil a 3.1 que tarda en el
fijo.

El problema que sigo teniendo es que maquina pongo en produccion, por
que una maquina multiprocesador creo que no aumentará el rendimiento
del sistema. Entonces creo que lo unico que puedo poner es un XEON
normal, no un XEON MP, o bien un AMD 64, no un AMD 64X2.

Alguna correccion o sugerencia????

Gracias.

"Miguel Egea" escribió en el
mensaje news:
primero ejecutas dbcc sqlperf(waitstats,clear)
ejecuts tus consultas
y despues
dbcc sqlperf(waitstats)


saludos

"GenioMaestro" wrote in message
news:
Como se monitorizan esas esperas CXPACKET??? Plis.

"Miguel Egea" escribió en el
mensaje news:
Revisa a ver si tienes muchas esperas CXPACKET, es decir esperas por
paralelismo usa el hint maxdop con valor 1 para no permitir
paralelismo y comprueba si has mejorado el rendimiento.

Saludos
Miguel Egea
"GenioMaestro" wrote in message
news:%
Hola a todos:

Tengo una aplicación desarrollada en sql 2005 que entrará en
produccion en septiembre, espero, y tengo algunos problemas que me
hacen dudar sobre la configuracion de la maquina de produccion.

Es un sistema de calculo bursatil. La base de datos tiene ya unos
15 GB y creciendo. La estructura interna es muy sencilla, tan solo
tengo dos tablas principales, una de cotizaciones con 8 campos y
otra de calculos con 53 campos. Pero eso si, cada tabla tiene unos
25 Millones de registros.

El programa lo he desarrollado en el portatil, un centrino 1.6 con
1 Gb de memoria y se mueve muy bien, usando el micro siempre por
encima del 80% y mucho tiempo al 100%, lo que veo normal porque
estoy haciendo muchos calculos matematicos y consultas bastante
complejas.

El problema lo tengo al pasar a la maquina grande de desarrollo. Es
un Pentium4 3.2 con HT, un 630 o 640 con 2 Gb de memoria y 200 Gb
de disco duro Sata2 de 3 Gbs y NCQ. En esta maquina, el uso del
procesador está cerca del 50% con un máximo del 55%. Parece como si
no usara el HT. Y sin embargo, los dos graficos se mueven en
paralelo, cuando uno sube el otro baja y viceversa.

En el portatil centrino no hay HT y supuse que al pasarlo a la
maquina grande, con un micro más potente, los tiempos mejorarían,
pero no es así. He probado a poner un Dual Core, que no es HT, pero
me pasa lo mismo. Los tiempos de calculo son exactamente los
mismos, tanto en el portatil como en el P4 con HT que con el Dual
Core.

Alguna idea de lo que puede estar pasando???? Que maquina pongo en
produccion si todas las maquinas me tardan lo mismo????

Todas las maquinas tienen Windows XP Pro SP2, y la version demo de
6 meses de Sql Server 2005 Enterprise.

Espero vuestras ideas y orientaciones.

Gracias.

























Respuesta Responder a este mensaje
#12 Miguel Egea
01/08/2006 - 09:06 | Informe spam
A ver si me explico

tu tiees un update que haces
update t
set campo= (subquery),
campo=(subquery)

y a esos campos les estás llamando maxnivelXX, necesitaría el scritp de las
tablas de origen, de la de destino y una descripción de que quieres
conseguir (el valor máximo de fecha de entrada para el cliente X o cosas de
este tipo). Mi objetivo es darte pistas de como reconstruir el query más
eficazmente..

Saludos
Miguel Egea

"GenioMaestro" wrote in message
news:epqM$%
Que descripcion necesitas??? No entiendo que quieres decir con uno o dos
niveles.

Y que parte del scrip de base de datos???


"Miguel Egea" escribió en el mensaje
news:
Creo que puede mejorarse, vamos a ver como, ¿nos pasas una descripcion de
uno o dos niveles del tema de cotizaciones yh el script?

Saludos
Miguel Egea
"GenioMaestro" wrote in message
news:
Puedo poner set statitisc io on y set statistics time on en el
administrador corporativo, lanzando una consulta o un procedimiento
almacenado y deciros lo que da, pero todas las consultas y funciones han
sido depuradas al limite. Os paso una de las operaciones mas pesadas.

update calculos set
Max_Nivel1 = ...,
Max_Nivel2 = ...,
Max_Nivel3 = ...,
Max_Nivel4 = ...,
Max_Nivel5 = ( select top 1 cierre from (SELECT TOP 2 cierre FROM (
SELECT TOP 1900 CIERRE FROM COTIZACIONES WITH (TABLOCKX)
WHERE COD_VALOR = @PASA_VALOR AND FECHA < (SELECT TOP 1 FECHA FROM
(SELECT TOP 600 FECHA FROM COTIZACIONES WITH (TABLOCKX) WHERE COD_VALOR
= @PASA_VALOR AND FECHA <= FECHA_CAL ORDER BY FECHA DESC) AS XX_TEMPO
ORDER BY FECHA ASC)
ORDER BY FECHA DESC) AS XX_TEMPO ORDER BY CIERRE DESC ) as xx_tempo2
order by cierre asc ) ,
Min_Nivel1 = ...,
Min_Nivel2 = ...,
Min_Nivel3 = ...,
Min_Nivel4 = ...,
Min_Nivel5 = ( select top 1 cierre from (SELECT TOP 2 cierre FROM (
SELECT TOP 1900 CIERRE FROM COTIZACIONES WITH (TABLOCKX)
WHERE COD_VALOR = @PASA_VALOR AND FECHA < (SELECT TOP 1 FECHA FROM
(SELECT TOP 600 FECHA FROM COTIZACIONES WITH (TABLOCKX) WHERE COD_VALOR
= @PASA_VALOR AND FECHA <= FECHA_CAL ORDER BY FECHA DESC) AS XX_TEMPO
ORDER BY FECHA ASC)
ORDER BY FECHA DESC) AS XX_TEMPO ORDER BY CIERRE ASC ) as xx_tempo2
order by cierre DESC )
FROM CALCULOS WITH (TABLOCKX)
where cod_valor = @PASA_VALOR
and FECHA_CAL >= @F_INI and FECHA_CAL < @F_FIN

Es un SELECT de SELECT de SELECT WHERE SUBSELECT de SUBSELECT, son 5
anidaciones. Es la septima version y hasta el momento es la más rapida
que conseguido. Empeze con un cursor que era terriblemente lento, luego
con WHERE fecha NOT IN (SELECT ...) y tambien era muy lento. Ademas
averigue que si lo calculaba desde una funcion de usuario UDF era más
lento que si lanzaba la consulta directamente en la clausula update,
osea que quite las funciones. Luego probe con optimizaciones como WITH
(TABLOCKX) y la cosa mejoro mucho. Esto es lo mas optimizado que he
conseguido. Puntualizo que aun quitando las optimizaciones WITH
(TABLOCKX) el micro HT hace lo mismo, pero tardando mas tiempo.

Los niveles 1,2,3 y 4 se calculan de la misma forma pero con otros
rangos TOP. Para averiguar el maximo se ordena en ascendente y para el
mínimo en descendente, por lo demas las consultas son identicas. En el
nivel 5 necesito procesar 2500 registros, 1900 + 600 = 2500, que
multiplicado por los 10.000 valores da la friolera de 25 millones de
registros. Por tanto, cada vez que calculo todos los valores de todos
los mercados, la fase 1 donde esta este update, se pasea por todos y
cada uno de los registros de cotizaciones.

El problema esta en que cuando pasemos a produccion, el cliente quiere
tener de 30.000 a 50.000 valores, lo que me da de 75 a 125 millones de
registros. Creo que voy a tener que particionar las tablas y los
indices, aunque el problema no es de disco duro, la cola de disco esta
siempre en cero con un maximo de 2.

Me extraña mucho que este proceso no sea paralelizable, solo son dos
select pesados, uno de 600 registros y otro de 1900, las otras tres
consultas solo sacan 1 registro o 2, una nimiedad para sql server, y
segun estoy escribiendo se me esta ocurriendo algo. Voy a probar y os
cuento.



"Miguel Egea" escribió en el mensaje
news:
de los que me parecen significativos las esperas tienes de dos tipos
pagelatch y pageiolatch una es contención de caché , la otra es
contención de disco, ninguna creo que sea especialmente significativa
ni que tenga que ver con tu proceso. Lo que si que podemos hacer es
optimización pura y dura

Si puedes ejecutar tu proceso poniento set statitisc io on, set
statistics time on después ejecutar tu proceso y pasarnos los
resultados podemos seguir mirando, No es que SQL sea una aplicacioŽn
indicada para hacer "calculo vectorial", pero no creo que en
operaciones "pequeñas" de cpu te vaya a suponer un cuello de botella,
tiene que haber algo más.

Saludos
Miguel Egea


"GenioMaestro" wrote in message
news:%
Me dice esto:

Total 89835 571562 578
SOS_SCHEDULER_YIELD 58124 312 296
PAGELATCH_EX 24534 93 78
SLEEP_BPOOL_FLUSH 3214 19109 140
WRITELOG 2467 2265 62
PAGEIOLATCH_SH 422 9796 0
PAGEIOLATCH_EX 380 4265 0
LAZYWRITER_SLEEP 269 267625 0
SLEEP_TASK 234 0 0
ASYNC_NETWORK_IO 115 31 0
SQLTRACE_BUFFER_FLUSH 67 268000 0
PAGEIOLATCH_UP 9 62 0


La fila de CXPACKET da cero en las tres columnas. Por tanto mi
problema no es por las esperas CXPACKET.

Creo que el problema es otro. No se exactamente donde lo he leido,
pero creo que lo unico que se puede paralelizar son las SELECT, no los
INSERT, ni los UPDATE, ni los DELETE.

Precisamente, el sistema de calculo lo que hace es, primero un INSERT
en la tabla calculos, y luego varios UPDATE en la misma tabla.

Lo que tengo es un registro en la tabla de calculos por cada registro
en la tabla de cotizaciones. Y luego calculo muchas cosas
interdependientes, es decir, algunos calculos se hacen mediante select
sobre la tabla de cotizaciones, pero otros se hacen con select de la
tabla calculos. Más claro. Las columnas 1 a 7 de la tabla calculos las
obtengo con una select sobre la tabla cotizaciones, pero para calcular
las columnas 8 a 11 necesito datos de las columnas 1 a 7 de la tabla
de calculos.

Creo el sistema de calculo no corre más porque no puede correr más. Si
desactivo el HT en el equipo grande, el uso de micro se mueve
exactamente igual que en el portatil, y los tiempos son ligeramente
inferiores, de 3.8 seg que tarda en el portatil a 3.1 que tarda en el
fijo.

El problema que sigo teniendo es que maquina pongo en produccion, por
que una maquina multiprocesador creo que no aumentará el rendimiento
del sistema. Entonces creo que lo unico que puedo poner es un XEON
normal, no un XEON MP, o bien un AMD 64, no un AMD 64X2.

Alguna correccion o sugerencia????

Gracias.

"Miguel Egea" escribió en el
mensaje news:
primero ejecutas dbcc sqlperf(waitstats,clear)
ejecuts tus consultas
y despues
dbcc sqlperf(waitstats)


saludos

"GenioMaestro" wrote in message
news:
Como se monitorizan esas esperas CXPACKET??? Plis.

"Miguel Egea" escribió en el
mensaje news:
Revisa a ver si tienes muchas esperas CXPACKET, es decir esperas
por paralelismo usa el hint maxdop con valor 1 para no permitir
paralelismo y comprueba si has mejorado el rendimiento.

Saludos
Miguel Egea
"GenioMaestro" wrote in message
news:%
Hola a todos:

Tengo una aplicación desarrollada en sql 2005 que entrará en
produccion en septiembre, espero, y tengo algunos problemas que me
hacen dudar sobre la configuracion de la maquina de produccion.

Es un sistema de calculo bursatil. La base de datos tiene ya unos
15 GB y creciendo. La estructura interna es muy sencilla, tan solo
tengo dos tablas principales, una de cotizaciones con 8 campos y
otra de calculos con 53 campos. Pero eso si, cada tabla tiene unos
25 Millones de registros.

El programa lo he desarrollado en el portatil, un centrino 1.6 con
1 Gb de memoria y se mueve muy bien, usando el micro siempre por
encima del 80% y mucho tiempo al 100%, lo que veo normal porque
estoy haciendo muchos calculos matematicos y consultas bastante
complejas.

El problema lo tengo al pasar a la maquina grande de desarrollo.
Es un Pentium4 3.2 con HT, un 630 o 640 con 2 Gb de memoria y 200
Gb de disco duro Sata2 de 3 Gbs y NCQ. En esta maquina, el uso del
procesador está cerca del 50% con un máximo del 55%. Parece como
si no usara el HT. Y sin embargo, los dos graficos se mueven en
paralelo, cuando uno sube el otro baja y viceversa.

En el portatil centrino no hay HT y supuse que al pasarlo a la
maquina grande, con un micro más potente, los tiempos mejorarían,
pero no es así. He probado a poner un Dual Core, que no es HT,
pero me pasa lo mismo. Los tiempos de calculo son exactamente los
mismos, tanto en el portatil como en el P4 con HT que con el Dual
Core.

Alguna idea de lo que puede estar pasando???? Que maquina pongo en
produccion si todas las maquinas me tardan lo mismo????

Todas las maquinas tienen Windows XP Pro SP2, y la version demo de
6 meses de Sql Server 2005 Enterprise.

Espero vuestras ideas y orientaciones.

Gracias.





























Respuesta Responder a este mensaje
#13 GenioMaestro
01/08/2006 - 11:17 | Informe spam
Vale, te explico. Es un sistema de calculo bursatil. Por tanto tengo miles
de valores en cada mercado(Nasdaq, Nyse, ...).

Cada valor tiene, para cada dia, Apertura, Maximo, Minimo, Cierre y Volumen.
Cada valor tiene un historico distinto dependiendo de la antiguedad del
valor, con una media de 250 cotizaciones por año. La mayoría de los valores
tienen un historico de 5 a 10 años, o más, lo que da entre 1250 y 2500
registros por valor, o más.

Hay que calcular una serie de cosas para cada día de cotizacion de cada
valor. Por tanto tengo el mismo número de registros en la tabla de calculos
y todas las formulas están referidas a la fecha de calculo.

Lo que tienen que hacer las consultas que os pase es:

Localizar el segundo cierre más alto de los 2500 registros saltando los 600
primeros ordenados por fecha.

Localizar el segundo cierre más bajo de los 2500 registros saltando los 600
primeros ordenados por fecha.

Por tanto, explicando mi consulta en varios pasos, lo que hace es:

1 Localizar la fecha del registro 600: Cojo los 600 primeros registros
para ese valor cuya fecha sea menor o igual que la del calculo, los ordeno
por fecha y cojo la fecha del primero ordenado por fecha, que es la que me
interesa, el punto de salto.
(SELECT TOP 1 FECHA FROM
(SELECT TOP 600 FECHA FROM COTIZACIONES WITH (TABLOCKX) WHERE COD_VALOR
= @PASA_VALOR AND FECHA <= FECHA_CAL ORDER BY FECHA DESC) AS XX_TEMPO
ORDER BY FECHA ASC)

2 Cojo los 1900 registros que estan debajo de esa fecha de corte
(SELECT TOP 1900 CIERRE FROM COTIZACIONES WITH (TABLOCKX)
WHERE COD_VALOR = @PASA_VALOR AND FECHA < xxx_fecha_corte ORDER BY FECHA
DESC)

3 Cojo los dos cierres más altos, ordenando por cierre en descendente y
luego cojo el cierre más bajo de esos dos ordenando en ascendente, lo que me
da exactamente lo que necesito.
( select top 1 cierre from (SELECT TOP 2 cierre FROM (-lista registros
seleccionados-)
AS XX_TEMPO ORDER BY CIERRE DESC ) as xx_tempo2
order by cierre asc )

Puede parecer que sobra tanto order by, pero es necesario porque estoy
usando siempre la clausula TOP, la cual solo funciona correctamente si está
acompañada de una clausula ORDER BY.

Para localizar los cierres más bajos, se hace lo mismo pero en el punto 3,
se cambia el asc por desc y viceversa.

Si necesitas estructura de datos y datos de prueba, avisame y te mando un
privado.

Gracias por el interes que te tomas.


"Miguel Egea" escribió en el mensaje
news:
A ver si me explico

tu tiees un update que haces
update t
set campo= (subquery),
campo=(subquery)

y a esos campos les estás llamando maxnivelXX, necesitaría el scritp de
las tablas de origen, de la de destino y una descripción de que quieres
conseguir (el valor máximo de fecha de entrada para el cliente X o cosas
de este tipo). Mi objetivo es darte pistas de como reconstruir el query
más eficazmente..

Saludos
Miguel Egea

"GenioMaestro" wrote in message
news:epqM$%
Que descripcion necesitas??? No entiendo que quieres decir con uno o dos
niveles.

Y que parte del scrip de base de datos???


"Miguel Egea" escribió en el mensaje
news:
Creo que puede mejorarse, vamos a ver como, ¿nos pasas una descripcion
de uno o dos niveles del tema de cotizaciones yh el script?

Saludos
Miguel Egea
"GenioMaestro" wrote in message
news:
Puedo poner set statitisc io on y set statistics time on en el
administrador corporativo, lanzando una consulta o un procedimiento
almacenado y deciros lo que da, pero todas las consultas y funciones
han sido depuradas al limite. Os paso una de las operaciones mas
pesadas.

update calculos set
Max_Nivel1 = ...,
Max_Nivel2 = ...,
Max_Nivel3 = ...,
Max_Nivel4 = ...,
Max_Nivel5 = ( select top 1 cierre from (SELECT TOP 2 cierre FROM (
SELECT TOP 1900 CIERRE FROM COTIZACIONES WITH (TABLOCKX)
WHERE COD_VALOR = @PASA_VALOR AND FECHA < (SELECT TOP 1 FECHA FROM
(SELECT TOP 600 FECHA FROM COTIZACIONES WITH (TABLOCKX) WHERE
COD_VALOR = @PASA_VALOR AND FECHA <= FECHA_CAL ORDER BY FECHA DESC) AS
XX_TEMPO ORDER BY FECHA ASC)
ORDER BY FECHA DESC) AS XX_TEMPO ORDER BY CIERRE DESC ) as xx_tempo2
order by cierre asc ) ,
Min_Nivel1 = ...,
Min_Nivel2 = ...,
Min_Nivel3 = ...,
Min_Nivel4 = ...,
Min_Nivel5 = ( select top 1 cierre from (SELECT TOP 2 cierre FROM (
SELECT TOP 1900 CIERRE FROM COTIZACIONES WITH (TABLOCKX)
WHERE COD_VALOR = @PASA_VALOR AND FECHA < (SELECT TOP 1 FECHA FROM
(SELECT TOP 600 FECHA FROM COTIZACIONES WITH (TABLOCKX) WHERE
COD_VALOR = @PASA_VALOR AND FECHA <= FECHA_CAL ORDER BY FECHA DESC) AS
XX_TEMPO ORDER BY FECHA ASC)
ORDER BY FECHA DESC) AS XX_TEMPO ORDER BY CIERRE ASC ) as xx_tempo2
order by cierre DESC )
FROM CALCULOS WITH (TABLOCKX)
where cod_valor = @PASA_VALOR
and FECHA_CAL >= @F_INI and FECHA_CAL < @F_FIN

Es un SELECT de SELECT de SELECT WHERE SUBSELECT de SUBSELECT, son 5
anidaciones. Es la septima version y hasta el momento es la más rapida
que conseguido. Empeze con un cursor que era terriblemente lento, luego
con WHERE fecha NOT IN (SELECT ...) y tambien era muy lento. Ademas
averigue que si lo calculaba desde una funcion de usuario UDF era más
lento que si lanzaba la consulta directamente en la clausula update,
osea que quite las funciones. Luego probe con optimizaciones como WITH
(TABLOCKX) y la cosa mejoro mucho. Esto es lo mas optimizado que he
conseguido. Puntualizo que aun quitando las optimizaciones WITH
(TABLOCKX) el micro HT hace lo mismo, pero tardando mas tiempo.

Los niveles 1,2,3 y 4 se calculan de la misma forma pero con otros
rangos TOP. Para averiguar el maximo se ordena en ascendente y para el
mínimo en descendente, por lo demas las consultas son identicas. En el
nivel 5 necesito procesar 2500 registros, 1900 + 600 = 2500, que
multiplicado por los 10.000 valores da la friolera de 25 millones de
registros. Por tanto, cada vez que calculo todos los valores de todos
los mercados, la fase 1 donde esta este update, se pasea por todos y
cada uno de los registros de cotizaciones.

El problema esta en que cuando pasemos a produccion, el cliente quiere
tener de 30.000 a 50.000 valores, lo que me da de 75 a 125 millones de
registros. Creo que voy a tener que particionar las tablas y los
indices, aunque el problema no es de disco duro, la cola de disco esta
siempre en cero con un maximo de 2.

Me extraña mucho que este proceso no sea paralelizable, solo son dos
select pesados, uno de 600 registros y otro de 1900, las otras tres
consultas solo sacan 1 registro o 2, una nimiedad para sql server, y
segun estoy escribiendo se me esta ocurriendo algo. Voy a probar y os
cuento.



"Miguel Egea" escribió en el
mensaje news:
de los que me parecen significativos las esperas tienes de dos tipos
pagelatch y pageiolatch una es contención de caché , la otra es
contención de disco, ninguna creo que sea especialmente significativa
ni que tenga que ver con tu proceso. Lo que si que podemos hacer es
optimización pura y dura

Si puedes ejecutar tu proceso poniento set statitisc io on, set
statistics time on después ejecutar tu proceso y pasarnos los
resultados podemos seguir mirando, No es que SQL sea una aplicacio´n
indicada para hacer "calculo vectorial", pero no creo que en
operaciones "pequeñas" de cpu te vaya a suponer un cuello de botella,
tiene que haber algo más.

Saludos
Miguel Egea


"GenioMaestro" wrote in message
news:%
Me dice esto:

Total 89835 571562 578
SOS_SCHEDULER_YIELD 58124 312 296
PAGELATCH_EX 24534 93 78
SLEEP_BPOOL_FLUSH 3214 19109 140
WRITELOG 2467 2265 62
PAGEIOLATCH_SH 422 9796 0
PAGEIOLATCH_EX 380 4265 0
LAZYWRITER_SLEEP 269 267625 0
SLEEP_TASK 234 0 0
ASYNC_NETWORK_IO 115 31 0
SQLTRACE_BUFFER_FLUSH 67 268000 0
PAGEIOLATCH_UP 9 62 0


La fila de CXPACKET da cero en las tres columnas. Por tanto mi
problema no es por las esperas CXPACKET.

Creo que el problema es otro. No se exactamente donde lo he leido,
pero creo que lo unico que se puede paralelizar son las SELECT, no
los INSERT, ni los UPDATE, ni los DELETE.

Precisamente, el sistema de calculo lo que hace es, primero un INSERT
en la tabla calculos, y luego varios UPDATE en la misma tabla.

Lo que tengo es un registro en la tabla de calculos por cada registro
en la tabla de cotizaciones. Y luego calculo muchas cosas
interdependientes, es decir, algunos calculos se hacen mediante
select sobre la tabla de cotizaciones, pero otros se hacen con select
de la tabla calculos. Más claro. Las columnas 1 a 7 de la tabla
calculos las obtengo con una select sobre la tabla cotizaciones, pero
para calcular las columnas 8 a 11 necesito datos de las columnas 1 a
7 de la tabla de calculos.

Creo el sistema de calculo no corre más porque no puede correr más.
Si desactivo el HT en el equipo grande, el uso de micro se mueve
exactamente igual que en el portatil, y los tiempos son ligeramente
inferiores, de 3.8 seg que tarda en el portatil a 3.1 que tarda en el
fijo.

El problema que sigo teniendo es que maquina pongo en produccion, por
que una maquina multiprocesador creo que no aumentará el rendimiento
del sistema. Entonces creo que lo unico que puedo poner es un XEON
normal, no un XEON MP, o bien un AMD 64, no un AMD 64X2.

Alguna correccion o sugerencia????

Gracias.

"Miguel Egea" escribió en el
mensaje news:
primero ejecutas dbcc sqlperf(waitstats,clear)
ejecuts tus consultas
y despues
dbcc sqlperf(waitstats)


saludos

"GenioMaestro" wrote in message
news:
Como se monitorizan esas esperas CXPACKET??? Plis.

"Miguel Egea" escribió en el
mensaje news:
Revisa a ver si tienes muchas esperas CXPACKET, es decir esperas
por paralelismo usa el hint maxdop con valor 1 para no permitir
paralelismo y comprueba si has mejorado el rendimiento.

Saludos
Miguel Egea
"GenioMaestro" wrote in message
news:%
Hola a todos:

Tengo una aplicación desarrollada en sql 2005 que entrará en
produccion en septiembre, espero, y tengo algunos problemas que
me hacen dudar sobre la configuracion de la maquina de
produccion.

Es un sistema de calculo bursatil. La base de datos tiene ya unos
15 GB y creciendo. La estructura interna es muy sencilla, tan
solo tengo dos tablas principales, una de cotizaciones con 8
campos y otra de calculos con 53 campos. Pero eso si, cada tabla
tiene unos 25 Millones de registros.

El programa lo he desarrollado en el portatil, un centrino 1.6
con 1 Gb de memoria y se mueve muy bien, usando el micro siempre
por encima del 80% y mucho tiempo al 100%, lo que veo normal
porque estoy haciendo muchos calculos matematicos y consultas
bastante complejas.

El problema lo tengo al pasar a la maquina grande de desarrollo.
Es un Pentium4 3.2 con HT, un 630 o 640 con 2 Gb de memoria y 200
Gb de disco duro Sata2 de 3 Gbs y NCQ. En esta maquina, el uso
del procesador está cerca del 50% con un máximo del 55%. Parece
como si no usara el HT. Y sin embargo, los dos graficos se mueven
en paralelo, cuando uno sube el otro baja y viceversa.

En el portatil centrino no hay HT y supuse que al pasarlo a la
maquina grande, con un micro más potente, los tiempos mejorarían,
pero no es así. He probado a poner un Dual Core, que no es HT,
pero me pasa lo mismo. Los tiempos de calculo son exactamente los
mismos, tanto en el portatil como en el P4 con HT que con el Dual
Core.

Alguna idea de lo que puede estar pasando???? Que maquina pongo
en produccion si todas las maquinas me tardan lo mismo????

Todas las maquinas tienen Windows XP Pro SP2, y la version demo
de 6 meses de Sql Server 2005 Enterprise.

Espero vuestras ideas y orientaciones.

Gracias.
































Respuesta Responder a este mensaje
#14 Miguel Egea
01/08/2006 - 17:37 | Informe spam
bueno, como el tread se llama algo de 2005 supongo que tienes 2005, si no,
por supuesto que también se puede hacer. Revisa esto, dame de alta en
messenger, como webmaster arroba portalsql.com y vemos como hay que hacerlo
para que sea más eficiente, el resultado lo posteamos en el grupo como
solucion..

drop table #valores
go
create table #valores(idValor int,
fecha smalldatetime,
maximo float,
minimo float,
apertura float,
cierre float,
orden smallint,
grupo smallint)
go

with mycte(fecha,maximo,minimo,apertura,cierre,row)
as
(
select getdate() Fecha,
rand()*9000 maximo,
rand()*1000 minimo,
rand()*1000 apertura,
rand()*1000 cierre,
1 row
union all
select Fecha-1,
rand(row)*maximo,
minimo,
apertura,
cierre,
row+1 as row
from myCte where row<2500
)
insert into #valores
(idvalor,fecha,maximo,minimo,apertura,cierre,orden,grupo)
select 123,fecha,maximo,minimo,apertura,cierre,row, case when row <600 then
1 else 2 end from mycte option (maxrecursion 0)
go

select * from (
select idvalor,fecha,maximo,minimo,apertura,cierre,
row_number() over(partition by grupo order by maximo) fila
from #valores
where grupo=2
) a
where fila in (1,2)


Saludos
Miguel Egea
"GenioMaestro" wrote in message
news:

Vale, te explico. Es un sistema de calculo bursatil. Por tanto tengo miles
de valores en cada mercado(Nasdaq, Nyse, ...).

Cada valor tiene, para cada dia, Apertura, Maximo, Minimo, Cierre y
Volumen. Cada valor tiene un historico distinto dependiendo de la
antiguedad del valor, con una media de 250 cotizaciones por año. La
mayoría de los valores tienen un historico de 5 a 10 años, o más, lo que
da entre 1250 y 2500 registros por valor, o más.

Hay que calcular una serie de cosas para cada día de cotizacion de cada
valor. Por tanto tengo el mismo número de registros en la tabla de
calculos y todas las formulas están referidas a la fecha de calculo.

Lo que tienen que hacer las consultas que os pase es:

Localizar el segundo cierre más alto de los 2500 registros saltando los
600 primeros ordenados por fecha.

Localizar el segundo cierre más bajo de los 2500 registros saltando los
600 primeros ordenados por fecha.

Por tanto, explicando mi consulta en varios pasos, lo que hace es:

1 Localizar la fecha del registro 600: Cojo los 600 primeros registros
para ese valor cuya fecha sea menor o igual que la del calculo, los ordeno
por fecha y cojo la fecha del primero ordenado por fecha, que es la que me
interesa, el punto de salto.
(SELECT TOP 1 FECHA FROM
(SELECT TOP 600 FECHA FROM COTIZACIONES WITH (TABLOCKX) WHERE COD_VALOR
= @PASA_VALOR AND FECHA <= FECHA_CAL ORDER BY FECHA DESC) AS XX_TEMPO
ORDER BY FECHA ASC)

2 Cojo los 1900 registros que estan debajo de esa fecha de corte
(SELECT TOP 1900 CIERRE FROM COTIZACIONES WITH (TABLOCKX)
WHERE COD_VALOR = @PASA_VALOR AND FECHA < xxx_fecha_corte ORDER BY FECHA
DESC)

3 Cojo los dos cierres más altos, ordenando por cierre en descendente y
luego cojo el cierre más bajo de esos dos ordenando en ascendente, lo que
me da exactamente lo que necesito.
( select top 1 cierre from (SELECT TOP 2 cierre FROM (-lista registros
seleccionados-)
AS XX_TEMPO ORDER BY CIERRE DESC ) as xx_tempo2
order by cierre asc )

Puede parecer que sobra tanto order by, pero es necesario porque estoy
usando siempre la clausula TOP, la cual solo funciona correctamente si
está acompañada de una clausula ORDER BY.

Para localizar los cierres más bajos, se hace lo mismo pero en el punto
3, se cambia el asc por desc y viceversa.

Si necesitas estructura de datos y datos de prueba, avisame y te mando un
privado.

Gracias por el interes que te tomas.


"Miguel Egea" escribió en el mensaje
news:
A ver si me explico

tu tiees un update que haces
update t
set campo= (subquery),
campo=(subquery)

y a esos campos les estás llamando maxnivelXX, necesitaría el scritp de
las tablas de origen, de la de destino y una descripción de que quieres
conseguir (el valor máximo de fecha de entrada para el cliente X o cosas
de este tipo). Mi objetivo es darte pistas de como reconstruir el query
más eficazmente..

Saludos
Miguel Egea

"GenioMaestro" wrote in message
news:epqM$%
Que descripcion necesitas??? No entiendo que quieres decir con uno o dos
niveles.

Y que parte del scrip de base de datos???


"Miguel Egea" escribió en el mensaje
news:
Creo que puede mejorarse, vamos a ver como, ¿nos pasas una descripcion
de uno o dos niveles del tema de cotizaciones yh el script?

Saludos
Miguel Egea
"GenioMaestro" wrote in message
news:
Puedo poner set statitisc io on y set statistics time on en el
administrador corporativo, lanzando una consulta o un procedimiento
almacenado y deciros lo que da, pero todas las consultas y funciones
han sido depuradas al limite. Os paso una de las operaciones mas
pesadas.

update calculos set
Max_Nivel1 = ...,
Max_Nivel2 = ...,
Max_Nivel3 = ...,
Max_Nivel4 = ...,
Max_Nivel5 = ( select top 1 cierre from (SELECT TOP 2 cierre FROM (
SELECT TOP 1900 CIERRE FROM COTIZACIONES WITH (TABLOCKX)
WHERE COD_VALOR = @PASA_VALOR AND FECHA < (SELECT TOP 1 FECHA FROM
(SELECT TOP 600 FECHA FROM COTIZACIONES WITH (TABLOCKX) WHERE
COD_VALOR = @PASA_VALOR AND FECHA <= FECHA_CAL ORDER BY FECHA DESC) AS
XX_TEMPO ORDER BY FECHA ASC)
ORDER BY FECHA DESC) AS XX_TEMPO ORDER BY CIERRE DESC ) as xx_tempo2
order by cierre asc ) ,
Min_Nivel1 = ...,
Min_Nivel2 = ...,
Min_Nivel3 = ...,
Min_Nivel4 = ...,
Min_Nivel5 = ( select top 1 cierre from (SELECT TOP 2 cierre FROM (
SELECT TOP 1900 CIERRE FROM COTIZACIONES WITH (TABLOCKX)
WHERE COD_VALOR = @PASA_VALOR AND FECHA < (SELECT TOP 1 FECHA FROM
(SELECT TOP 600 FECHA FROM COTIZACIONES WITH (TABLOCKX) WHERE
COD_VALOR = @PASA_VALOR AND FECHA <= FECHA_CAL ORDER BY FECHA DESC) AS
XX_TEMPO ORDER BY FECHA ASC)
ORDER BY FECHA DESC) AS XX_TEMPO ORDER BY CIERRE ASC ) as xx_tempo2
order by cierre DESC )
FROM CALCULOS WITH (TABLOCKX)
where cod_valor = @PASA_VALOR
and FECHA_CAL >= @F_INI and FECHA_CAL < @F_FIN

Es un SELECT de SELECT de SELECT WHERE SUBSELECT de SUBSELECT, son 5
anidaciones. Es la septima version y hasta el momento es la más rapida
que conseguido. Empeze con un cursor que era terriblemente lento,
luego con WHERE fecha NOT IN (SELECT ...) y tambien era muy lento.
Ademas averigue que si lo calculaba desde una funcion de usuario UDF
era más lento que si lanzaba la consulta directamente en la clausula
update, osea que quite las funciones. Luego probe con optimizaciones
como WITH (TABLOCKX) y la cosa mejoro mucho. Esto es lo mas optimizado
que he conseguido. Puntualizo que aun quitando las optimizaciones WITH
(TABLOCKX) el micro HT hace lo mismo, pero tardando mas tiempo.

Los niveles 1,2,3 y 4 se calculan de la misma forma pero con otros
rangos TOP. Para averiguar el maximo se ordena en ascendente y para el
mínimo en descendente, por lo demas las consultas son identicas. En el
nivel 5 necesito procesar 2500 registros, 1900 + 600 = 2500, que
multiplicado por los 10.000 valores da la friolera de 25 millones de
registros. Por tanto, cada vez que calculo todos los valores de todos
los mercados, la fase 1 donde esta este update, se pasea por todos y
cada uno de los registros de cotizaciones.

El problema esta en que cuando pasemos a produccion, el cliente quiere
tener de 30.000 a 50.000 valores, lo que me da de 75 a 125 millones de
registros. Creo que voy a tener que particionar las tablas y los
indices, aunque el problema no es de disco duro, la cola de disco esta
siempre en cero con un maximo de 2.

Me extraña mucho que este proceso no sea paralelizable, solo son dos
select pesados, uno de 600 registros y otro de 1900, las otras tres
consultas solo sacan 1 registro o 2, una nimiedad para sql server, y
segun estoy escribiendo se me esta ocurriendo algo. Voy a probar y os
cuento.



"Miguel Egea" escribió en el
mensaje news:
de los que me parecen significativos las esperas tienes de dos tipos
pagelatch y pageiolatch una es contención de caché , la otra es
contención de disco, ninguna creo que sea especialmente significativa
ni que tenga que ver con tu proceso. Lo que si que podemos hacer es
optimización pura y dura

Si puedes ejecutar tu proceso poniento set statitisc io on, set
statistics time on después ejecutar tu proceso y pasarnos los
resultados podemos seguir mirando, No es que SQL sea una aplicacioŽn
indicada para hacer "calculo vectorial", pero no creo que en
operaciones "pequeñas" de cpu te vaya a suponer un cuello de botella,
tiene que haber algo más.

Saludos
Miguel Egea


"GenioMaestro" wrote in message
news:%
Me dice esto:

Total 89835 571562 578
SOS_SCHEDULER_YIELD 58124 312 296
PAGELATCH_EX 24534 93 78
SLEEP_BPOOL_FLUSH 3214 19109 140
WRITELOG 2467 2265 62
PAGEIOLATCH_SH 422 9796 0
PAGEIOLATCH_EX 380 4265 0
LAZYWRITER_SLEEP 269 267625 0
SLEEP_TASK 234 0 0
ASYNC_NETWORK_IO 115 31 0
SQLTRACE_BUFFER_FLUSH 67 268000 0
PAGEIOLATCH_UP 9 62 0


La fila de CXPACKET da cero en las tres columnas. Por tanto mi
problema no es por las esperas CXPACKET.

Creo que el problema es otro. No se exactamente donde lo he leido,
pero creo que lo unico que se puede paralelizar son las SELECT, no
los INSERT, ni los UPDATE, ni los DELETE.

Precisamente, el sistema de calculo lo que hace es, primero un
INSERT en la tabla calculos, y luego varios UPDATE en la misma
tabla.

Lo que tengo es un registro en la tabla de calculos por cada
registro en la tabla de cotizaciones. Y luego calculo muchas cosas
interdependientes, es decir, algunos calculos se hacen mediante
select sobre la tabla de cotizaciones, pero otros se hacen con
select de la tabla calculos. Más claro. Las columnas 1 a 7 de la
tabla calculos las obtengo con una select sobre la tabla
cotizaciones, pero para calcular las columnas 8 a 11 necesito datos
de las columnas 1 a 7 de la tabla de calculos.

Creo el sistema de calculo no corre más porque no puede correr más.
Si desactivo el HT en el equipo grande, el uso de micro se mueve
exactamente igual que en el portatil, y los tiempos son ligeramente
inferiores, de 3.8 seg que tarda en el portatil a 3.1 que tarda en
el fijo.

El problema que sigo teniendo es que maquina pongo en produccion,
por que una maquina multiprocesador creo que no aumentará el
rendimiento del sistema. Entonces creo que lo unico que puedo poner
es un XEON normal, no un XEON MP, o bien un AMD 64, no un AMD 64X2.

Alguna correccion o sugerencia????

Gracias.

"Miguel Egea" escribió en el
mensaje news:
primero ejecutas dbcc sqlperf(waitstats,clear)
ejecuts tus consultas
y despues
dbcc sqlperf(waitstats)


saludos

"GenioMaestro" wrote in message
news:
Como se monitorizan esas esperas CXPACKET??? Plis.

"Miguel Egea" escribió en el
mensaje news:
Revisa a ver si tienes muchas esperas CXPACKET, es decir esperas
por paralelismo usa el hint maxdop con valor 1 para no permitir
paralelismo y comprueba si has mejorado el rendimiento.

Saludos
Miguel Egea
"GenioMaestro" wrote in message
news:%
Hola a todos:

Tengo una aplicación desarrollada en sql 2005 que entrará en
produccion en septiembre, espero, y tengo algunos problemas que
me hacen dudar sobre la configuracion de la maquina de
produccion.

Es un sistema de calculo bursatil. La base de datos tiene ya
unos 15 GB y creciendo. La estructura interna es muy sencilla,
tan solo tengo dos tablas principales, una de cotizaciones con 8
campos y otra de calculos con 53 campos. Pero eso si, cada tabla
tiene unos 25 Millones de registros.

El programa lo he desarrollado en el portatil, un centrino 1.6
con 1 Gb de memoria y se mueve muy bien, usando el micro siempre
por encima del 80% y mucho tiempo al 100%, lo que veo normal
porque estoy haciendo muchos calculos matematicos y consultas
bastante complejas.

El problema lo tengo al pasar a la maquina grande de desarrollo.
Es un Pentium4 3.2 con HT, un 630 o 640 con 2 Gb de memoria y
200 Gb de disco duro Sata2 de 3 Gbs y NCQ. En esta maquina, el
uso del procesador está cerca del 50% con un máximo del 55%.
Parece como si no usara el HT. Y sin embargo, los dos graficos
se mueven en paralelo, cuando uno sube el otro baja y viceversa.

En el portatil centrino no hay HT y supuse que al pasarlo a la
maquina grande, con un micro más potente, los tiempos
mejorarían, pero no es así. He probado a poner un Dual Core, que
no es HT, pero me pasa lo mismo. Los tiempos de calculo son
exactamente los mismos, tanto en el portatil como en el P4 con
HT que con el Dual Core.

Alguna idea de lo que puede estar pasando???? Que maquina pongo
en produccion si todas las maquinas me tardan lo mismo????

Todas las maquinas tienen Windows XP Pro SP2, y la version demo
de 6 meses de Sql Server 2005 Enterprise.

Espero vuestras ideas y orientaciones.

Gracias.




































Respuesta Responder a este mensaje
#15 GenioMaestro
01/08/2006 - 21:10 | Informe spam
Muchas gracias Miguel, tu rutina de creacion de datos me la guardo como oro
en paño, es fantastica.

Nunca se me habia ocurrido hacer una funcion recursiva como esta para crear
datos. Es buenisima.

Aparte. En algún punto no me he explicado bien o no me has entendido bien.
Verás.

Cuando digo que hay que calcular para cada día de cotizacion, me refiero a
que mecesito un max_nivel5 y un min_nivel5 para cada fecha de cotización. Y
si debajo de esa fecha no hay 1900 registros, pues los que haya, y si hay
cero registros porque nisiquiera llegan a 600, pues nada, no hay ni
max_nivel5 ni min_nivel5, da nulo.

Es decir, tu, al generar los registros has puesto un contador hasta 600 y
luego usas partition by grupo para separar los bloques. Usar partition ya lo
intenté yo sin exito, porque, según tu idea, tengo que regenerar el contador
para cada fecha de cotizacion. Más claro:

Contando desde hoy 01/08/2006 hacia atrás, el punto de corte es el
10/12/2004, pero para la fecha 31/07/2006, el punto de corte es el
09/12/2004, es decir, cada fecha y cada valor, tienen un punto de corte
distinto que, segun tu idea, tengo que recalcular, cosa que puede tardar
mucho y usar mucha IO. Aparte, como verás tengo 5 niveles, osea trabajo
multiplicado por 5. Por eso yo calculo el punto de corte de forma dinámica
con una select.

Te apunto al messenger y te paso un scrip con mi tabla, unos datos de prueba
y la consulta completa.

Un saludo.



"Miguel Egea" escribió en el mensaje
news:
bueno, como el tread se llama algo de 2005 supongo que tienes 2005, si no,
por supuesto que también se puede hacer. Revisa esto, dame de alta en
messenger, como webmaster arroba portalsql.com y vemos como hay que
hacerlo para que sea más eficiente, el resultado lo posteamos en el grupo
como solucion..

drop table #valores
go
create table #valores(idValor int,
fecha smalldatetime,
maximo float,
minimo float,
apertura float,
cierre float,
orden smallint,
grupo smallint)
go

with mycte(fecha,maximo,minimo,apertura,cierre,row)
as
(
select getdate() Fecha,
rand()*9000 maximo,
rand()*1000 minimo,
rand()*1000 apertura,
rand()*1000 cierre,
1 row
union all
select Fecha-1,
rand(row)*maximo,
minimo,
apertura,
cierre,
row+1 as row
from myCte where row<2500
)
insert into #valores
(idvalor,fecha,maximo,minimo,apertura,cierre,orden,grupo)
select 123,fecha,maximo,minimo,apertura,cierre,row, case when row <600
then 1 else 2 end from mycte option (maxrecursion 0)
go

select * from (
select idvalor,fecha,maximo,minimo,apertura,cierre,
row_number() over(partition by grupo order by maximo) fila
from #valores
where grupo=2
) a
where fila in (1,2)


Saludos
Miguel Egea
"GenioMaestro" wrote in message
news:

Vale, te explico. Es un sistema de calculo bursatil. Por tanto tengo
miles de valores en cada mercado(Nasdaq, Nyse, ...).

Cada valor tiene, para cada dia, Apertura, Maximo, Minimo, Cierre y
Volumen. Cada valor tiene un historico distinto dependiendo de la
antiguedad del valor, con una media de 250 cotizaciones por año. La
mayoría de los valores tienen un historico de 5 a 10 años, o más, lo que
da entre 1250 y 2500 registros por valor, o más.

Hay que calcular una serie de cosas para cada día de cotizacion de cada
valor. Por tanto tengo el mismo número de registros en la tabla de
calculos y todas las formulas están referidas a la fecha de calculo.

Lo que tienen que hacer las consultas que os pase es:

Localizar el segundo cierre más alto de los 2500 registros saltando los
600 primeros ordenados por fecha.

Localizar el segundo cierre más bajo de los 2500 registros saltando los
600 primeros ordenados por fecha.

Por tanto, explicando mi consulta en varios pasos, lo que hace es:

1 Localizar la fecha del registro 600: Cojo los 600 primeros registros
para ese valor cuya fecha sea menor o igual que la del calculo, los
ordeno por fecha y cojo la fecha del primero ordenado por fecha, que es
la que me interesa, el punto de salto.
(SELECT TOP 1 FECHA FROM
(SELECT TOP 600 FECHA FROM COTIZACIONES WITH (TABLOCKX) WHERE COD_VALOR
= @PASA_VALOR AND FECHA <= FECHA_CAL ORDER BY FECHA DESC) AS XX_TEMPO
ORDER BY FECHA ASC)

2 Cojo los 1900 registros que estan debajo de esa fecha de corte
(SELECT TOP 1900 CIERRE FROM COTIZACIONES WITH (TABLOCKX)
WHERE COD_VALOR = @PASA_VALOR AND FECHA < xxx_fecha_corte ORDER BY FECHA
DESC)

3 Cojo los dos cierres más altos, ordenando por cierre en descendente y
luego cojo el cierre más bajo de esos dos ordenando en ascendente, lo que
me da exactamente lo que necesito.
( select top 1 cierre from (SELECT TOP 2 cierre FROM (-lista registros
seleccionados-)
AS XX_TEMPO ORDER BY CIERRE DESC ) as xx_tempo2
order by cierre asc )

Puede parecer que sobra tanto order by, pero es necesario porque estoy
usando siempre la clausula TOP, la cual solo funciona correctamente si
está acompañada de una clausula ORDER BY.

Para localizar los cierres más bajos, se hace lo mismo pero en el punto
3, se cambia el asc por desc y viceversa.

Si necesitas estructura de datos y datos de prueba, avisame y te mando un
privado.

Gracias por el interes que te tomas.


"Miguel Egea" escribió en el mensaje
news:
A ver si me explico

tu tiees un update que haces
update t
set campo= (subquery),
campo=(subquery)

y a esos campos les estás llamando maxnivelXX, necesitaría el scritp de
las tablas de origen, de la de destino y una descripción de que quieres
conseguir (el valor máximo de fecha de entrada para el cliente X o cosas
de este tipo). Mi objetivo es darte pistas de como reconstruir el query
más eficazmente..

Saludos
Miguel Egea

"GenioMaestro" wrote in message
news:epqM$%
Que descripcion necesitas??? No entiendo que quieres decir con uno o
dos niveles.

Y que parte del scrip de base de datos???


"Miguel Egea" escribió en el
mensaje news:
Creo que puede mejorarse, vamos a ver como, ¿nos pasas una descripcion
de uno o dos niveles del tema de cotizaciones yh el script?

Saludos
Miguel Egea
"GenioMaestro" wrote in message
news:
Puedo poner set statitisc io on y set statistics time on en el
administrador corporativo, lanzando una consulta o un procedimiento
almacenado y deciros lo que da, pero todas las consultas y funciones
han sido depuradas al limite. Os paso una de las operaciones mas
pesadas.

update calculos set
Max_Nivel1 = ...,
Max_Nivel2 = ...,
Max_Nivel3 = ...,
Max_Nivel4 = ...,
Max_Nivel5 = ( select top 1 cierre from (SELECT TOP 2 cierre FROM (
SELECT TOP 1900 CIERRE FROM COTIZACIONES WITH (TABLOCKX)
WHERE COD_VALOR = @PASA_VALOR AND FECHA < (SELECT TOP 1 FECHA FROM
(SELECT TOP 600 FECHA FROM COTIZACIONES WITH (TABLOCKX) WHERE
COD_VALOR = @PASA_VALOR AND FECHA <= FECHA_CAL ORDER BY FECHA DESC)
AS XX_TEMPO ORDER BY FECHA ASC)
ORDER BY FECHA DESC) AS XX_TEMPO ORDER BY CIERRE DESC ) as xx_tempo2
order by cierre asc ) ,
Min_Nivel1 = ...,
Min_Nivel2 = ...,
Min_Nivel3 = ...,
Min_Nivel4 = ...,
Min_Nivel5 = ( select top 1 cierre from (SELECT TOP 2 cierre FROM (
SELECT TOP 1900 CIERRE FROM COTIZACIONES WITH (TABLOCKX)
WHERE COD_VALOR = @PASA_VALOR AND FECHA < (SELECT TOP 1 FECHA FROM
(SELECT TOP 600 FECHA FROM COTIZACIONES WITH (TABLOCKX) WHERE
COD_VALOR = @PASA_VALOR AND FECHA <= FECHA_CAL ORDER BY FECHA DESC)
AS XX_TEMPO ORDER BY FECHA ASC)
ORDER BY FECHA DESC) AS XX_TEMPO ORDER BY CIERRE ASC ) as xx_tempo2
order by cierre DESC )
FROM CALCULOS WITH (TABLOCKX)
where cod_valor = @PASA_VALOR
and FECHA_CAL >= @F_INI and FECHA_CAL < @F_FIN

Es un SELECT de SELECT de SELECT WHERE SUBSELECT de SUBSELECT, son 5
anidaciones. Es la septima version y hasta el momento es la más
rapida que conseguido. Empeze con un cursor que era terriblemente
lento, luego con WHERE fecha NOT IN (SELECT ...) y tambien era muy
lento. Ademas averigue que si lo calculaba desde una funcion de
usuario UDF era más lento que si lanzaba la consulta directamente en
la clausula update, osea que quite las funciones. Luego probe con
optimizaciones como WITH (TABLOCKX) y la cosa mejoro mucho. Esto es
lo mas optimizado que he conseguido. Puntualizo que aun quitando las
optimizaciones WITH (TABLOCKX) el micro HT hace lo mismo, pero
tardando mas tiempo.

Los niveles 1,2,3 y 4 se calculan de la misma forma pero con otros
rangos TOP. Para averiguar el maximo se ordena en ascendente y para
el mínimo en descendente, por lo demas las consultas son identicas.
En el nivel 5 necesito procesar 2500 registros, 1900 + 600 = 2500,
que multiplicado por los 10.000 valores da la friolera de 25 millones
de registros. Por tanto, cada vez que calculo todos los valores de
todos los mercados, la fase 1 donde esta este update, se pasea por
todos y cada uno de los registros de cotizaciones.

El problema esta en que cuando pasemos a produccion, el cliente
quiere tener de 30.000 a 50.000 valores, lo que me da de 75 a 125
millones de registros. Creo que voy a tener que particionar las
tablas y los indices, aunque el problema no es de disco duro, la cola
de disco esta siempre en cero con un maximo de 2.

Me extraña mucho que este proceso no sea paralelizable, solo son dos
select pesados, uno de 600 registros y otro de 1900, las otras tres
consultas solo sacan 1 registro o 2, una nimiedad para sql server, y
segun estoy escribiendo se me esta ocurriendo algo. Voy a probar y os
cuento.



"Miguel Egea" escribió en el
mensaje news:
de los que me parecen significativos las esperas tienes de dos tipos
pagelatch y pageiolatch una es contención de caché , la otra es
contención de disco, ninguna creo que sea especialmente
significativa ni que tenga que ver con tu proceso. Lo que si que
podemos hacer es optimización pura y dura

Si puedes ejecutar tu proceso poniento set statitisc io on, set
statistics time on después ejecutar tu proceso y pasarnos los
resultados podemos seguir mirando, No es que SQL sea una aplicacio´n
indicada para hacer "calculo vectorial", pero no creo que en
operaciones "pequeñas" de cpu te vaya a suponer un cuello de
botella, tiene que haber algo más.

Saludos
Miguel Egea


"GenioMaestro" wrote in message
news:%
Me dice esto:

Total 89835 571562 578
SOS_SCHEDULER_YIELD 58124 312 296
PAGELATCH_EX 24534 93 78
SLEEP_BPOOL_FLUSH 3214 19109 140
WRITELOG 2467 2265 62
PAGEIOLATCH_SH 422 9796 0
PAGEIOLATCH_EX 380 4265 0
LAZYWRITER_SLEEP 269 267625 0
SLEEP_TASK 234 0 0
ASYNC_NETWORK_IO 115 31 0
SQLTRACE_BUFFER_FLUSH 67 268000 0
PAGEIOLATCH_UP 9 62 0


La fila de CXPACKET da cero en las tres columnas. Por tanto mi
problema no es por las esperas CXPACKET.

Creo que el problema es otro. No se exactamente donde lo he leido,
pero creo que lo unico que se puede paralelizar son las SELECT, no
los INSERT, ni los UPDATE, ni los DELETE.

Precisamente, el sistema de calculo lo que hace es, primero un
INSERT en la tabla calculos, y luego varios UPDATE en la misma
tabla.

Lo que tengo es un registro en la tabla de calculos por cada
registro en la tabla de cotizaciones. Y luego calculo muchas cosas
interdependientes, es decir, algunos calculos se hacen mediante
select sobre la tabla de cotizaciones, pero otros se hacen con
select de la tabla calculos. Más claro. Las columnas 1 a 7 de la
tabla calculos las obtengo con una select sobre la tabla
cotizaciones, pero para calcular las columnas 8 a 11 necesito datos
de las columnas 1 a 7 de la tabla de calculos.

Creo el sistema de calculo no corre más porque no puede correr más.
Si desactivo el HT en el equipo grande, el uso de micro se mueve
exactamente igual que en el portatil, y los tiempos son ligeramente
inferiores, de 3.8 seg que tarda en el portatil a 3.1 que tarda en
el fijo.

El problema que sigo teniendo es que maquina pongo en produccion,
por que una maquina multiprocesador creo que no aumentará el
rendimiento del sistema. Entonces creo que lo unico que puedo poner
es un XEON normal, no un XEON MP, o bien un AMD 64, no un AMD 64X2.

Alguna correccion o sugerencia????

Gracias.

"Miguel Egea" escribió en el
mensaje news:
primero ejecutas dbcc sqlperf(waitstats,clear)
ejecuts tus consultas
y despues
dbcc sqlperf(waitstats)


saludos

"GenioMaestro" wrote in message
news:
Como se monitorizan esas esperas CXPACKET??? Plis.

"Miguel Egea" escribió en el
mensaje
news:
Revisa a ver si tienes muchas esperas CXPACKET, es decir esperas
por paralelismo usa el hint maxdop con valor 1 para no permitir
paralelismo y comprueba si has mejorado el rendimiento.

Saludos
Miguel Egea
"GenioMaestro" wrote in message
news:%
Hola a todos:

Tengo una aplicación desarrollada en sql 2005 que entrará en
produccion en septiembre, espero, y tengo algunos problemas que
me hacen dudar sobre la configuracion de la maquina de
produccion.

Es un sistema de calculo bursatil. La base de datos tiene ya
unos 15 GB y creciendo. La estructura interna es muy sencilla,
tan solo tengo dos tablas principales, una de cotizaciones con
8 campos y otra de calculos con 53 campos. Pero eso si, cada
tabla tiene unos 25 Millones de registros.

El programa lo he desarrollado en el portatil, un centrino 1.6
con 1 Gb de memoria y se mueve muy bien, usando el micro
siempre por encima del 80% y mucho tiempo al 100%, lo que veo
normal porque estoy haciendo muchos calculos matematicos y
consultas bastante complejas.

El problema lo tengo al pasar a la maquina grande de
desarrollo. Es un Pentium4 3.2 con HT, un 630 o 640 con 2 Gb de
memoria y 200 Gb de disco duro Sata2 de 3 Gbs y NCQ. En esta
maquina, el uso del procesador está cerca del 50% con un máximo
del 55%. Parece como si no usara el HT. Y sin embargo, los dos
graficos se mueven en paralelo, cuando uno sube el otro baja y
viceversa.

En el portatil centrino no hay HT y supuse que al pasarlo a la
maquina grande, con un micro más potente, los tiempos
mejorarían, pero no es así. He probado a poner un Dual Core,
que no es HT, pero me pasa lo mismo. Los tiempos de calculo son
exactamente los mismos, tanto en el portatil como en el P4 con
HT que con el Dual Core.

Alguna idea de lo que puede estar pasando???? Que maquina pongo
en produccion si todas las maquinas me tardan lo mismo????

Todas las maquinas tienen Windows XP Pro SP2, y la version demo
de 6 meses de Sql Server 2005 Enterprise.

Espero vuestras ideas y orientaciones.

Gracias.







































email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida