Ayuda para un novato.

24/02/2007 - 11:38 por Enrique | Informe spam
Hola a todos.

Estoy comenzando a usar los procedimientos almacenados, los estoy
ejecutando desde fox, pasandole algunos parametros.

La pregunta es porque si ejecuto un procedimiento pasandole parametros se
trada el doble de tiempo, que si lo ejecutara sin pasarle parametros, es
decir con valores fijos

Caso 1
Select * from mitabla where Codigo = @lcCodigo

Caso 2
Select * from mitabla where Codigo = '0001'

Gracias.

Preguntas similare

Leer las respuestas

#11 Alejandro Mesa
26/02/2007 - 15:11 | Informe spam
Enrique,

Perdón que abuse más de ustedes, pero porque las gran diferencia al
cambiar de char a varchar, es obvio que debo cambiar todo a varchar, pero
quisiera saber su opinión.



Espera un momento, no tienes que cambiar todo a varchar. El tipo de dato
"char" es un tipo de dato fijo, osea que se espera que la mayoria de los
valores que se van a almacenar tnegan una longitud similar. SQL Server
adiciona espacios en los tipo de columna "char" para forzar lo dicho
anteriormente. En el caso de los "varchar" es diferente. este se usa cuando
la longitud de los valores que se van a almacenar fluctua y para salvar
espacio, pues usamos este tipo de data de longitud variable. Pongamos el
ejemplo de el nombre de una compañia, nombres cortos como "Microsoft" y
largos como "Banco Agricola de el Pais de las Maravillas".

Por que te dije que cambiaras de "char" a "varchar", pues porque al usar
"char", los valores de las cuentas son rellenados con espacio y es por eso
que para comparar si la cuenta "1101" es hija de "11" entonces usas RTRIM,
LEN, etc. No puedes usar "char" con el operador LIKE porque al concatenar el
caracter '%', la cuenta quedaria como:

'1 %'

y por lo tanto la condicion:

'1101 ' LIKE '1 %'

daria como resultado FALSO.

Asi que para evitar RTRIM, LEN, etc, y poder usar el operador LIKE, te
propuse cambiar esa columna de "char" a "varchar" y en caso de que los
espacios a la derecha prevalecieran, actualizar la tabla para eliminar esos
espacios.



AMB

"Enrique" wrote:

Muchisimas Gracias

Cambie a VarChar, y ahora se tarda tan solo 7 segundos, grandioso.
Perdón que abuse más de ustedes, pero porque las gran diferencia al
cambiar de char a varchar, es obvio que debo cambiar todo a varchar, pero
quisiera saber su opinión.

Gracias de nuevo.

"Jose Mariano Alvarez"
escribió en el
mensaje news:
> Por que no agreagas columnas calculadas e indices por esas columnas
> calculadas?
> De esa manera solucionas el problema de acceso por indices?
>
>
>
>
> Saludos
> Ing. Jose Mariano Alvarez
>
>
> (Cambia los ceros por O y saca lo que sobra)
>
>
>
>
> "Enrique" wrote in message
> news:
>> Gracias por responder
>>
>> Las columnas son de tipo caracter, necesito usar esas funciones por que
>> el catalgo de cuentas es algo asi:
>>
>> 1
>> 11
>> 1101
>> 110101
>> 1102
>> 110201
>>
>> Pero de las partidas solo tienen movimiento las cuentas de detalle
>> 110101, pero debo calcular los saldos de todas, donde 11, debe abarcar
>> los totales de 1101,
>> 110101, 1102, 110201.
>>
>>
>>
>> "Alejandro Mesa" escribió en el
>> mensaje news:
>>> Enrique,
>>>
>>> 1 - Primero vamos a conversar sobre la sentencia "select" que estas
>>> usando.
>>> En esta haces uso de tres queries correlacionados para calcular
>>> [SldAnt],
>>> [Cargos] y [Abonos]. Estos queries se ejecutan por cada fila de la tabla
>>> [Catalogo] que cumple con la condicion que tienes en la clausula
>>> "where". La
>>> mayoria de las veces, estos queries correlacionados pueden expresarse
>>> mediante uniones de la tabla principal con las tabla que usa el query
>>> correlacionado, y como resultado se obtiene mejor rendimiento.
>>>
>>> select
>>> A.CodCta,
>>> A.NomCta,
>>> A.TipSal as Tipo,
>>> (CASE WHEN A.CtaDetalle = 1 then 'S' else 'N' end) as TipCta,
>>> SUM(
>>> CASE WHEN B.FecPda < @FecIni THEN CASE WHEN A.TipSal = 'D' THEN
>>> (B.Cargo-B.Abono) ELSE (B.Abono-B.Cargo) END ELSE 0 END
>>> ) as SldAnt,
>>> SUM(CASE WHEN B.FecPda >= @FecIni and B.FecPda <= @FecFin THEN B.Cargo
>>> ELSE
>>> 0 END) as Cargos,
>>> SUM(CASE WHEN B.FecPda >= @FecIni and B.FecPda <= @FecFin THEN B.Abono
>>> ELSE
>>> 0 END) as Abonos
>>> FROM
>>> dbo.Catalogo A
>>> inner join
>>> dbo.DetPartida B
>>> on CodEmp = @CodEmp
>>> and LEFT(RTrim(B.CodCta), len(rtrim(A.CodCta))) = Rtrim(A.CodCta)
>>> WHERE
>>> A.CodEmp = @CodEmp
>>> and Rtrim(A.CodCta) >= @CtaIni
>>> and Rtrim(A.CodCta) <= @CtaFin
>>> and len(rtrim(A.CodCta)) >= @LenMin
>>> and len(rtrim(A.CodCta)) <= @LenMax
>>>
>>> 2 - No es buena practica manipular las columnas que participan en una
>>> union
>>> o en el filtro de la clausula "where", porque SQL Server no usara las
>>> estadisticas de distribucion de los indices por esas columnas, en caso
>>> de
>>> existir, y por lo tanto el plan de ejecucion que se escoja tendra mas
>>> costo
>>> que si no manipulamos las columnas. Me refiero a:
>>>
>>> - LEFT(RTrim(B.CodCta), len(rtrim(A.CodCta))) = Rtrim(A.CodCta)
>>> - and Rtrim(A.CodCta) >= @CtaIni
>>> - and Rtrim(A.CodCta) <= @CtaFin
>>> - and len(rtrim(A.CodCta)) >= @LenMin
>>> - and len(rtrim(A.CodCta)) <= @LenMax
>>>
>>> Por que estas usando las funciones LEFT, RTRIM, LEN en estos casos,
>>> puedes
>>> decirme cual es el tipo de data de esas columnas?
>>>
>>>
>>> AMB
>>>
>>>
>>> "Enrique" wrote:
>>>
>>>> Gracias por responder
>>>>
>>>> Este es el Procedimiento Almacenado:
>>>>
>>>> CREATE PROCEDURE imprimir_Balanza @CodEmp Char(3), @LenMin int, @LenMax
>>>> int,
>>>> @CtaIni as Char(20), @CtaFin Char(20), @FecIni Char(8), @Fecfin Char(8)
>>>> AS
>>>> SELECT A.CodCta, A.NomCta, A.TipSal as Tipo, (case when CtaDetalle = 1
>>>> then
>>>> 'S' else 'N' end) as TipCta,
>>>> (case when TipSal = 'D' then
>>>> (SELECT SUM(B.Cargo-B.Abono) FROM dbo.DetPartida B WHERE CodEmp =
>>>> @CodEmp
>>>> and LEFT(RTrim(B.CodCta), len(rtrim(A.CodCta))) = Rtrim(A.CodCta) and
>>>> FecPda
>>>> < @FecIni)
>>>> else
>>>> (SELECT SUM(B.Abono-B.Cargo) FROM dbo.DetPartida B WHERE CodEmp =
>>>> @CodEmp
>>>> and LEFT(RTrim(B.CodCta), len(rtrim(A.CodCta))) = Rtrim(A.CodCta) and
>>>> FecPda
>>>> < @FecIni)
>>>> end) as SldAnt,
>>>> (Select Sum(B.Cargo) FROM dbo.DetPartida B WHERE CodEmp = @CodEmp and
>>>> LEFT(RTrim(B.CodCta), len(rtrim(A.CodCta))) = Rtrim(A.CodCta) and
>>>> FecPda >> >>>> @FecIni and FecPda <= @FecFin) as Cargos,
>>>> (Select Sum(B.Abono) FROM dbo.DetPartida B WHERE CodEmp = @CodEmp and
>>>> LEFT(RTrim(B.CodCta), len(rtrim(A.CodCta))) = Rtrim(A.CodCta) and
>>>> FecPda >> >>>> @FecIni and FecPda <= @FecFin) as Abonos
>>>> FROM dbo.Catalogo A WHERE CodEmp = @CodEmp and Rtrim(A.CodCta) >=
>>>> @CtaIni
>>>> and Rtrim(A.CodCta) <= @CtaFin and len(rtrim(A.CodCta)) >= @LenMin and
>>>> len(rtrim(A.CodCta)) <= @LenMax
>>>> GO
>>>>
>>>> uso SQL 2000, auque podria usar el 2005 Express. Y estoy usando fox 9.0
>>>> Sp1.
>>>>
>>>> Asi lo llamo desde fox:
>>>> lnConn = SQLCONNECT("GeoDNS",'GeoUser','GeoUser')
>>>> SET DATE ANSI
>>>>
>>>> lcCommand = "Exec Imprimir_Balanza '"+Parametros.CodEmp+"',
>>>> "+ALLTRIM(STR(thisform.txtLongMin.Value))+", "+;
>>>>
>>>> ALLTRIM(STR(thisform.txtLonMax.Value))+",
>>>> '"+ALLTRIM(thisform.txtCtaIni.Value)+"',
>>>> '"+ALLTRIM(thisform.txtCtaFin.Value)+"','20"+;
>>>>
>>>> +ALLTRIM(STRTRAN(DTOC(Parametros.FecFin-DAY(Parametros.Fecfin)+1),'.',''))+"',
>>>> '20"+ALLTRIM(STRTRAN(DTOC(Parametros.Fecfin),'.',''))+"'"
>>>>
>>>> SET DATE DMY
>>>>
>>>> SQLEXEC(lnConn, lcCommand, 'ltBalanza')
>>>>
>>>> SQLDISCONNECT(lnConn)
>>>>
>>>> La finalidad del formulario es imprimir una balanza de comprobación, en
>>>> un
>>>> sistema de contablididad, te agradeceré mucho tu respuesta, pues me
>>>> preocupan mucho los tiempos de respuestas del sistema.
>>>>
>>>> Debo aclarar que siempre he usado subrutinas propias de fox, pero
>>>> alguien me
>>>> recomendo que usara procedimientos almacenados para mejorar los tiempos
>>>> de
>>>> respuesta, pero la subrutina original de fox se tarda 25 seg. y el
>>>> procedimiento de tarda 53 seg. y el volumen de datos que espero será
>>>> muchicimo mayor que con el que estoy probando actualmente.
>>>>
>>>>
>>>>
>>>> Gracias.
>>>>
>>>>
>>>> "Alejandro Mesa" escribió en
>>>> el
>>>> mensaje news:
>>>> > Hola Enrique,
>>>> >
>>>> > - Puedes postear el procedimiento almacenado y como lo estas
>>>> > llamando?
>>>> > - Que version de SQL Server estas usando?
>>>> > - Como lo llamas desde foxpro?
>>>> >
>>>> > AMB
>>>> >
>>>> > "Enrique" wrote:
>>>> >
>>>> >> Hola a todos.
>>>> >>
>>>> >> Estoy comenzando a usar los procedimientos almacenados, los estoy
>>>> >> ejecutando desde fox, pasandole algunos parametros.
>>>> >>
>>>> >> La pregunta es porque si ejecuto un procedimiento pasandole
>>>> >> parametros
>>>> >> se
>>>> >> trada el doble de tiempo, que si lo ejecutara sin pasarle
>>>> >> parametros, es
>>>> >> decir con valores fijos
>>>> >>
>>>> >> Caso 1
>>>> >> Select * from mitabla where Codigo = @lcCodigo
>>>> >>
>>>> >> Caso 2
>>>> >> Select * from mitabla where Codigo = '0001'
>>>> >>
>>>> >> Gracias.
>>>> >>
>>>> >>
>>>> >>
>>>>
>>>>
>>>>
>>
>>
>
>



Respuesta Responder a este mensaje
#12 Enrique
26/02/2007 - 16:21 | Informe spam
Muchas gracias de nuevo, aun no he intentado usar like, pero ya lo voy a
probar, aunque ya he conseguido unos 7 segundos de proceso que son muy
buenos.


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

Perdón que abuse más de ustedes, pero porque las gran diferencia al
cambiar de char a varchar, es obvio que debo cambiar todo a varchar, pero
quisiera saber su opinión.



Espera un momento, no tienes que cambiar todo a varchar. El tipo de dato
"char" es un tipo de dato fijo, osea que se espera que la mayoria de los
valores que se van a almacenar tnegan una longitud similar. SQL Server
adiciona espacios en los tipo de columna "char" para forzar lo dicho
anteriormente. En el caso de los "varchar" es diferente. este se usa
cuando
la longitud de los valores que se van a almacenar fluctua y para salvar
espacio, pues usamos este tipo de data de longitud variable. Pongamos el
ejemplo de el nombre de una compañia, nombres cortos como "Microsoft" y
largos como "Banco Agricola de el Pais de las Maravillas".

Por que te dije que cambiaras de "char" a "varchar", pues porque al usar
"char", los valores de las cuentas son rellenados con espacio y es por eso
que para comparar si la cuenta "1101" es hija de "11" entonces usas RTRIM,
LEN, etc. No puedes usar "char" con el operador LIKE porque al concatenar
el
caracter '%', la cuenta quedaria como:

'1 %'

y por lo tanto la condicion:

'1101 ' LIKE '1 %'

daria como resultado FALSO.

Asi que para evitar RTRIM, LEN, etc, y poder usar el operador LIKE, te
propuse cambiar esa columna de "char" a "varchar" y en caso de que los
espacios a la derecha prevalecieran, actualizar la tabla para eliminar
esos
espacios.



AMB

"Enrique" wrote:

Muchisimas Gracias

Cambie a VarChar, y ahora se tarda tan solo 7 segundos, grandioso.
Perdón que abuse más de ustedes, pero porque las gran diferencia al
cambiar de char a varchar, es obvio que debo cambiar todo a varchar, pero
quisiera saber su opinión.

Gracias de nuevo.

"Jose Mariano Alvarez"
escribió en el
mensaje news:
> Por que no agreagas columnas calculadas e indices por esas columnas
> calculadas?
> De esa manera solucionas el problema de acceso por indices?
>
>
>
>
> Saludos
> Ing. Jose Mariano Alvarez
>
>
> (Cambia los ceros por O y saca lo que sobra)
>
>
>
>
> "Enrique" wrote in message
> news:
>> Gracias por responder
>>
>> Las columnas son de tipo caracter, necesito usar esas funciones por
>> que
>> el catalgo de cuentas es algo asi:
>>
>> 1
>> 11
>> 1101
>> 110101
>> 1102
>> 110201
>>
>> Pero de las partidas solo tienen movimiento las cuentas de detalle
>> 110101, pero debo calcular los saldos de todas, donde 11, debe abarcar
>> los totales de 1101,
>> 110101, 1102, 110201.
>>
>>
>>
>> "Alejandro Mesa" escribió en
>> el
>> mensaje news:
>>> Enrique,
>>>
>>> 1 - Primero vamos a conversar sobre la sentencia "select" que estas
>>> usando.
>>> En esta haces uso de tres queries correlacionados para calcular
>>> [SldAnt],
>>> [Cargos] y [Abonos]. Estos queries se ejecutan por cada fila de la
>>> tabla
>>> [Catalogo] que cumple con la condicion que tienes en la clausula
>>> "where". La
>>> mayoria de las veces, estos queries correlacionados pueden expresarse
>>> mediante uniones de la tabla principal con las tabla que usa el query
>>> correlacionado, y como resultado se obtiene mejor rendimiento.
>>>
>>> select
>>> A.CodCta,
>>> A.NomCta,
>>> A.TipSal as Tipo,
>>> (CASE WHEN A.CtaDetalle = 1 then 'S' else 'N' end) as TipCta,
>>> SUM(
>>> CASE WHEN B.FecPda < @FecIni THEN CASE WHEN A.TipSal = 'D' THEN
>>> (B.Cargo-B.Abono) ELSE (B.Abono-B.Cargo) END ELSE 0 END
>>> ) as SldAnt,
>>> SUM(CASE WHEN B.FecPda >= @FecIni and B.FecPda <= @FecFin THEN
>>> B.Cargo
>>> ELSE
>>> 0 END) as Cargos,
>>> SUM(CASE WHEN B.FecPda >= @FecIni and B.FecPda <= @FecFin THEN
>>> B.Abono
>>> ELSE
>>> 0 END) as Abonos
>>> FROM
>>> dbo.Catalogo A
>>> inner join
>>> dbo.DetPartida B
>>> on CodEmp = @CodEmp
>>> and LEFT(RTrim(B.CodCta), len(rtrim(A.CodCta))) = Rtrim(A.CodCta)
>>> WHERE
>>> A.CodEmp = @CodEmp
>>> and Rtrim(A.CodCta) >= @CtaIni
>>> and Rtrim(A.CodCta) <= @CtaFin
>>> and len(rtrim(A.CodCta)) >= @LenMin
>>> and len(rtrim(A.CodCta)) <= @LenMax
>>>
>>> 2 - No es buena practica manipular las columnas que participan en una
>>> union
>>> o en el filtro de la clausula "where", porque SQL Server no usara las
>>> estadisticas de distribucion de los indices por esas columnas, en
>>> caso
>>> de
>>> existir, y por lo tanto el plan de ejecucion que se escoja tendra mas
>>> costo
>>> que si no manipulamos las columnas. Me refiero a:
>>>
>>> - LEFT(RTrim(B.CodCta), len(rtrim(A.CodCta))) = Rtrim(A.CodCta)
>>> - and Rtrim(A.CodCta) >= @CtaIni
>>> - and Rtrim(A.CodCta) <= @CtaFin
>>> - and len(rtrim(A.CodCta)) >= @LenMin
>>> - and len(rtrim(A.CodCta)) <= @LenMax
>>>
>>> Por que estas usando las funciones LEFT, RTRIM, LEN en estos casos,
>>> puedes
>>> decirme cual es el tipo de data de esas columnas?
>>>
>>>
>>> AMB
>>>
>>>
>>> "Enrique" wrote:
>>>
>>>> Gracias por responder
>>>>
>>>> Este es el Procedimiento Almacenado:
>>>>
>>>> CREATE PROCEDURE imprimir_Balanza @CodEmp Char(3), @LenMin int,
>>>> @LenMax
>>>> int,
>>>> @CtaIni as Char(20), @CtaFin Char(20), @FecIni Char(8), @Fecfin
>>>> Char(8)
>>>> AS
>>>> SELECT A.CodCta, A.NomCta, A.TipSal as Tipo, (case when CtaDetalle =
>>>> 1
>>>> then
>>>> 'S' else 'N' end) as TipCta,
>>>> (case when TipSal = 'D' then
>>>> (SELECT SUM(B.Cargo-B.Abono) FROM dbo.DetPartida B WHERE CodEmp >> >>>> @CodEmp
>>>> and LEFT(RTrim(B.CodCta), len(rtrim(A.CodCta))) = Rtrim(A.CodCta)
>>>> and
>>>> FecPda
>>>> < @FecIni)
>>>> else
>>>> (SELECT SUM(B.Abono-B.Cargo) FROM dbo.DetPartida B WHERE CodEmp >> >>>> @CodEmp
>>>> and LEFT(RTrim(B.CodCta), len(rtrim(A.CodCta))) = Rtrim(A.CodCta)
>>>> and
>>>> FecPda
>>>> < @FecIni)
>>>> end) as SldAnt,
>>>> (Select Sum(B.Cargo) FROM dbo.DetPartida B WHERE CodEmp = @CodEmp
>>>> and
>>>> LEFT(RTrim(B.CodCta), len(rtrim(A.CodCta))) = Rtrim(A.CodCta) and
>>>> FecPda >>> >>>> @FecIni and FecPda <= @FecFin) as Cargos,
>>>> (Select Sum(B.Abono) FROM dbo.DetPartida B WHERE CodEmp = @CodEmp
>>>> and
>>>> LEFT(RTrim(B.CodCta), len(rtrim(A.CodCta))) = Rtrim(A.CodCta) and
>>>> FecPda >>> >>>> @FecIni and FecPda <= @FecFin) as Abonos
>>>> FROM dbo.Catalogo A WHERE CodEmp = @CodEmp and Rtrim(A.CodCta) >>> >>>> @CtaIni
>>>> and Rtrim(A.CodCta) <= @CtaFin and len(rtrim(A.CodCta)) >= @LenMin
>>>> and
>>>> len(rtrim(A.CodCta)) <= @LenMax
>>>> GO
>>>>
>>>> uso SQL 2000, auque podria usar el 2005 Express. Y estoy usando fox
>>>> 9.0
>>>> Sp1.
>>>>
>>>> Asi lo llamo desde fox:
>>>> lnConn = SQLCONNECT("GeoDNS",'GeoUser','GeoUser')
>>>> SET DATE ANSI
>>>>
>>>> lcCommand = "Exec Imprimir_Balanza '"+Parametros.CodEmp+"',
>>>> "+ALLTRIM(STR(thisform.txtLongMin.Value))+", "+;
>>>>
>>>> ALLTRIM(STR(thisform.txtLonMax.Value))+",
>>>> '"+ALLTRIM(thisform.txtCtaIni.Value)+"',
>>>> '"+ALLTRIM(thisform.txtCtaFin.Value)+"','20"+;
>>>>
>>>> +ALLTRIM(STRTRAN(DTOC(Parametros.FecFin-DAY(Parametros.Fecfin)+1),'.',''))+"',
>>>> '20"+ALLTRIM(STRTRAN(DTOC(Parametros.Fecfin),'.',''))+"'"
>>>>
>>>> SET DATE DMY
>>>>
>>>> SQLEXEC(lnConn, lcCommand, 'ltBalanza')
>>>>
>>>> SQLDISCONNECT(lnConn)
>>>>
>>>> La finalidad del formulario es imprimir una balanza de comprobación,
>>>> en
>>>> un
>>>> sistema de contablididad, te agradeceré mucho tu respuesta, pues me
>>>> preocupan mucho los tiempos de respuestas del sistema.
>>>>
>>>> Debo aclarar que siempre he usado subrutinas propias de fox, pero
>>>> alguien me
>>>> recomendo que usara procedimientos almacenados para mejorar los
>>>> tiempos
>>>> de
>>>> respuesta, pero la subrutina original de fox se tarda 25 seg. y el
>>>> procedimiento de tarda 53 seg. y el volumen de datos que espero será
>>>> muchicimo mayor que con el que estoy probando actualmente.
>>>>
>>>>
>>>>
>>>> Gracias.
>>>>
>>>>
>>>> "Alejandro Mesa" escribió
>>>> en
>>>> el
>>>> mensaje news:
>>>> > Hola Enrique,
>>>> >
>>>> > - Puedes postear el procedimiento almacenado y como lo estas
>>>> > llamando?
>>>> > - Que version de SQL Server estas usando?
>>>> > - Como lo llamas desde foxpro?
>>>> >
>>>> > AMB
>>>> >
>>>> > "Enrique" wrote:
>>>> >
>>>> >> Hola a todos.
>>>> >>
>>>> >> Estoy comenzando a usar los procedimientos almacenados, los
>>>> >> estoy
>>>> >> ejecutando desde fox, pasandole algunos parametros.
>>>> >>
>>>> >> La pregunta es porque si ejecuto un procedimiento pasandole
>>>> >> parametros
>>>> >> se
>>>> >> trada el doble de tiempo, que si lo ejecutara sin pasarle
>>>> >> parametros, es
>>>> >> decir con valores fijos
>>>> >>
>>>> >> Caso 1
>>>> >> Select * from mitabla where Codigo = @lcCodigo
>>>> >>
>>>> >> Caso 2
>>>> >> Select * from mitabla where Codigo = '0001'
>>>> >>
>>>> >> Gracias.
>>>> >>
>>>> >>
>>>> >>
>>>>
>>>>
>>>>
>>
>>
>
>



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