Optimizar consultas SQL

Distintas formas de optimizar las consultas realizadas en SQL.
El lenguaje SQL es no procedimental, es decir, en las sentencias se indica que queremos conseguir y no como lo tiene que hacer el interprete para conseguirlo. Esto es pura teoría, pues en la práctica a todos los gestores de SQL hay que especificar sus propios truquitos para optimizar el rendimiento.

Por tanto, muchas veces no basta con especificar una sentencia SQL correcta, sino que además, hay que indicarle como tiene que hacerlo si queremos que el tiempo de respuesta sea el mínimo. En este apartado veremos como mejorar el tiempo de respuesta de nuestro interprete ante unas determinadas situaciones:

Diseño de las tablas

  • Normaliza las tablas, al menos hasta la tercera forma normal, para asegurar que no hay duplicidad de datos y se aprovecha al máximo el almacenamiento en las tablas. Si hay que desnormalizar alguna tabla piensa en la ocupación y en el rendimiento antes de proceder.
  • Los primeros campos de cada tabla deben ser aquellos campos requeridos y dentro de los requeridos primero se definen los de longitud fija y después los de longitud variable.
  • Ajusta al máximo el tamaño de los campos para no desperdiciar espacio.
  • Es muy habitual dejar un campo de texto para observaciones en las tablas. Si este campo se va a utilizar con poca frecuencia o si se ha definido con gran tamaño, por si acaso, es mejor crear una nueva tabla que contenga la clave primaria de la primera y el campo para observaciones.
Gestión y elección de los índices

Los índices son campos elegidos arbitrariamente por el constructor de la base de datos que permiten la búsqueda a partir de dicho campo a una velocidad notablemente superior. Sin embargo, esta ventaja se ve contrarrestada por el hecho de ocupar mucha más memoria (el doble más o menos) y de requerir para su inserción y actualización un tiempo de proceso superior.

Evidentemente, no podemos indexar todos los campos de una tabla extensa ya que doblamos el tamaño de la base de datos. Igualmente, tampoco sirve de mucho el indexar todos los campos en una tabla pequeña ya que las selecciones pueden efectuarse rápidamente de todos modos.

Un caso en el que los índices pueden resultar muy útiles es cuando realizamos peticiones simultáneas sobre varias tablas. En este caso, el proceso de selección puede acelerarse sensiblemente si indexamos los campos que sirven de nexo entre las dos tablas.

Los índices pueden resultar contraproducentes si los introducimos sobre campos triviales a partir de los cuales no se realiza ningún tipo de petición ya que, además del problema de memoria ya mencionado, estamos ralentizando otras tareas de la base de datos como son la edición, inserción y borrado. Es por ello que vale la pena pensárselo dos veces antes de indexar un campo que no sirve de criterio para búsquedas o que es usado con muy poca frecuencia por razones de mantenimiento.

Campos a Seleccionar

  • En la medida de lo posible hay que evitar que las sentencias SQL estén embebidas dentro del código de la aplicación. Es mucho más eficaz usar vistas o procedimientos almacenados por que el gestor los guarda compilados. Si se trata de una sentencia embebida el gestor debe compilarla antes de ejecutarla.
  • Seleccionar exclusivamente aquellos que se necesiten
  • No utilizar nunca SELECT * por que el gestor debe leer primero la estructura de la tabla antes de ejecutar la sentencia
  • Si utilizas varias tablas en la consulta especifica siempre a que tabla pertenece cada campo, le ahorras al gestor el tiempo de localizar a que tabla pertenece el campo. En lugar de SELECT Nombre, Factura FROM Clientes, Facturacion WHERE IdCliente = IdClienteFacturado, usa: SELECT Clientes.Nombre, Facturacion.Factura WHERE Clientes.IdCliente = Facturacion.IdClienteFacturado.
Campos de Filtro

  • Se procurará elegir en la cláusula WHERE aquellos campos que formen parte de la clave del fichero por el cual interrogamos. Además se especificarán en el mismo orden en el que estén definidos en la clave.
  • Interrogar siempre por campos que sean clave.
  • Si deseamos interrogar por campos pertenecientes a índices compuestos es mejor utilizar todos los campos de todos los índices. Supongamos que tenemos un índice formado por el campo NOMBRE y el campo APELLIDO y otro índice formado por el campo EDAD. La sentencia WHERE NOMBRE='Juan' AND APELLIDO Like '%' AND EDAD = 20 sería más optima que WHERE NOMBRE = 'Juan' AND EDAD = 20 por que el gestor, en este segundo caso, no puede usar el primer índice y ambas sentencias son equivalentes por que la condición APELLIDO Like '%' devolvería todos los registros.
Orden de las Tablas

Cuando se utilizan varias tablas dentro de la consulta hay que tener cuidado con el orden empleado en la cláusula FROM. Si deseamos saber cuantos alumnos se matricularon en el año 1996 y escribimos: FROM Alumnos, Matriculas WHERE Alumno.IdAlumno = Matriculas.IdAlumno AND Matriculas.Año = 1996 el gestor recorrerá todos los alumnos para buscar sus matriculas y devolver las correspondientes. Si escribimos FROM Matriculas, Alumnos WHERE Matriculas.Año = 1996 AND Matriculas.IdAlumno = Alumnos.IdAlumnos, el gestor filtra las matrículas y después selecciona los alumnos, de esta forma tiene que recorrer menos registros.

Autor

Claudio

Compartir

Comentarios

Daniel

04/11/2005
Me parece interante tu artículo, pero hay que recordar lo siguiente para cuando manejas gran volúmen de datos:

1. Es preferible realizar las relaciones entra tablas usando INNER JOIN, LEFT JOIN, RIGHT JOIN ... y no realizar la relación con la cláusula WHERE.
2. No se recomienda usar cláusula muy frecuentes como LIKE
3. Utilizar lo menos posible ANY, SOME, EXISTS, IN (SELECT Campo1 From Tabla2)
4. Utilizar FILEGROUPS, lo q permite asignar una base de datos, tabla, indices o determinados campos TEXT o IMAGES hacia diferentes archivos, lo cual permite una excelente aceleración.
5. Colocar las bases de datos en diferentes discos duros
6. Configurar los campos con la misma intercalación.
5. No utilizar cursores!!!!!
6. No utilizar tablas temporales con # o ##
7. Utilizar para poco volumen de datos en lugar de cursores las llamadas variables tipo tablas: DECLARE T1 TABLE (CAMPO1 VARCHAR(1))
8. Utilizar vistas en lugar de consultas gigantes en tus StoreProc. o mezclar el uso de estas, porque recordemos que las vistas son ya pre-compiladas.

Saludos
Daniel Yafac
Lima - Perú

Antonio

04/11/2005
A veces, sobre todo para tablas cuya especifación acerca de los campos puede variar, como clientes, etc. aporta ventajas crear tablas con datos genericos. Por ejemplo, podemos crear una tabla de valores ENTEROS (integer), con un valor que puede ser un char(2) para identificar grupos de valores y dos campos mas que nos indiquen un valor ajeno de clave primaria y otro de valor de dato. Viola casi todas las normas de diseño, pero personalmente he de deciros que en algunos casos es muy práctico.
Por ejemplo.
Create table params(param char(3), descrip char(30);
insert into params values('ES','Idioma español');
Create table valores(param char(2), valor integer, valor2 integer)


Antonio

04/11/2005
Tener en cuenta también que la creación de indices puede ser ASC (ascendente) o DESC (descendente). Que el orden de los campos a la hora de crear el índice es importante a la hora de hacer la consulta (mismo orden + rápido).
Evitar las creación de tablas temporales con LOG para los sistemas Informix p.e.

Juan Pablo Touron

03/12/2007
todo bien, pero ojo, esto solo funciona en ADO 2.8 para arriba o en SQL server 2000.

Para usar el LIKE en ADO 2.7 para abajo deben cambiarse los comodines '%' por los comodines '*' (asteriscos). De no hacerlo el LIKE funcionara buscando un STRING que contenga el %

Ejemplos:

BUSCA TODO LO Q TENGA H EN Mi_Campo en ADO <= 2.7
SELECT * FROM Mi_Tabla WHERE Mi_Campo LIKE '*H*'

BUSCA TODO LO Q TENGA H EN Mi_Campo en ADO >= 2.8 y SQL SERVER
SELECT * FROM Mi_Tabla WHERE Mi_Campo LIKE '%H%'

Espero les sea util, estos cambios estan muy mal documentados en las referencias de MSDN y demas, y realemente rompen mucho la paciencia... NUNCA SUPE POR QUE HACEN ESTAS COSAS...

Aptiliux

03/3/2008
lo primero, si la consulta que se está haciendo es realmente lenta, es desglosarla para ver en que parte de la consulta se encuentra la mayor lentitud, luego de identificarlo, probar si con un índice optimizas el tiempo de respuesta, si a mejorado pero la diferencia es muy poca, puedes utilizar consultas anidadas para definir el orden en el que el manejador realizaría la consulta, los niveles mas profundos se ejecutan primero, entonces debemos comenzar a limitar el volumen de data en estos niveles, e intentar dejar la consulta mas lenta para el nivel mas alto, pues en teoría debería haber menos data en esos niveles. Un modelo anidado de selects me funcionó en una consulta larga que la base de comparación eran fecha. No me gusta mucho utilizar joins pues la consulta es menos legible, pero es bueno saber que es mas rápido.

Rodrigo

03/4/2009
Ojo, muchos se pueden tentar con crear índices para acelerar sus consultas, pero estas no tienen ninguna validez si el campo indizado se consulta a través de alguna función SQL... En este caso se debe crear el indice incorporando la función.

jrd

27/10/2009
Tunning
La mejor forma de hacer tunning es revisando el manual de oracle donde puedes encontrar variedad de ejmplos y no comentarios confusos y muy pero muy basicos.

sendyourquery

12/1/2010
Otros errores comunes
Hola.

Muy bueno el artículo.

Comentar algunos errores comunes observados en numerosas instalaciones:
1) En uniones de consultas es mejor el uso de UNION ALL en vez de UNION si ambas subconsultas no pueden devolver datos repetidos.
2) Las LEFT JOIN y RIGHT JOIN son en realidad OUTER JOINs a pesar de que no se explicite la palabra OUTER.
3) En el uso de índices no es necesario utilizar todos los campos del mismo pero no es óptimo utilizar un campo si no se han informado los campos previos por igualdad .

Hemos creado una página web para la optimización de querys con problemas de rendimiento:

www.sendyourquery.com

Un saludo.

julian

11/2/2010
error de redacción
Estimados amigos, econtre un error de redacción en el articulo optimizar consultas SQL
TEXTO ORIGINAL
En lugar de SELECT Nombre, Factura FROM Clientes, Facturacion WHERE IdCliente = IdClienteFacturado, usa: SELECT Clientes.Nombre, Facturacion.Factura WHERE Clientes.IdCliente = Facturacion.IdClienteFacturado.

TEXTO CORRECTO
En lugar de SELECT Nombre, Factura FROM Clientes, Facturacion WHERE IdCliente = IdClienteFacturado, usa: SELECT Clientes.Nombre, Facturacion.Factura FROM Clientes, Facturacion WHERE Clientes.IdCliente = Facturacion.IdClienteFacturado.

Jesus

15/4/2010
Mi SP Tiene Rendimiento?
esta es la estructura de mis SP en SQL:


set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
/*----------------------------------------------------------------
PROPOSITO : Permite Listar Ordenes de Compra Trenes Peru Rail
AUTOR : Jesus Echevarria
FECHA : 15/MAR/10
INPUTS :
OUTPUTS : Lista de Ordenes de Compra Trenes Peru Rail
------------------------------------------------------------------
EXEC P_OrdenCompraTrenListar Null,Null,Null,Null,Null,Null,Null,Null,Null,Null,'A'
SELECT * FROM OrdenCompraTren
----------------------------------------------------------------*/
ALTER Procedure [dbo].[P_OrdenCompraTrenListar]
@IDOrdenCompraTren int=null,
@IDOrdenCompra Int=Null,
@IDServicioTren int=null,
@IDFile Int=null,
@FechaEmisionIni Datetime = NULL,
@FechaEmisionFin Datetime = NULL,
@CodigoReservaTren varchar(100)=Null,
@NroOpeDep varChar(100)=Null,
@EstadoTipSer Char(1)=Null,
@IDTipoMoneda int=null,
@EstadoDetTren char(1)=Null
As
Select IDOrdenCompraTren,
OCT.IDOrdenCompra,
OCT.IDServicioTren,
ST.DescripcionSerTren,
OCT.IDFile,
Isnull(FC.NomenclaturaFile,'')as NomenclaturaFile,
GrupoPaxTren,
Isnull(PaxIda,0)as PaxIda,
Isnull(NinoIda,0)as NinoIda,
Isnull(GuiaIda,0)as GuiaIda,
Isnull(MasajistaIda,0)as MasajistaIda,
Isnull(OtrosIda,0)as OtrosIda,
Isnull(PaxVuelta,0)as PaxVuelta,
Isnull(NinoVuelta,0)as NinoVuelta,
Isnull(GuiaVuelta,0)as GuiaVuelta,
Isnull(MasajistaVuelta,0)as MasajistaVuelta,
Isnull(OtrosVuelta,0)as OtrosVuelta,
Isnull(PrePaxIda,0)as PrePaxIda,
Isnull(PreNinIda,0)as PreNinIda,
Isnull(PreGuiIda,0)as PreGuiIda,
Isnull(PreMasIda,0)as PreMasIda,
Isnull(PreOtroIda,0)as PreOtroIda,
Isnull(PrePaxVue,0)as PrePaxVue,
Isnull(PreNinVue,0)as PreNinVue,
Isnull(PreGuiVue,0)as PreGuiVue,
Isnull(PreMasVue,0)as PreMasVue,
Isnull(PreOtroVue,0)as PreOtroVue,
TotalTren,
ISNULL(CodigoReservaTren,'')as CodigoReservaTren,
ISNULL(NroOpeDep,'')as NroOpeDep,
SaldoTotal,
Case ISNULL(EstadoTipSer,'')
When 'G' then 'Generado'
When 'A' then 'Aprobado'
End as EstadoTipSer,
isNull(DBO.FU_Tren_ID(IDTrenIda),'')as TrenIda,
isNull(DBO.FU_Tren_ID(IDTrenvuelta),'')as TrenVuelta,
OC.IDTipoMoneda,
IsNull(TM.TipoMonedaDescripcion,'')as TipoMonedaDescripcion,
Isnull(Convert(char(10),OC.FechaEmision,103),'')as FechaEmision,
Isnull(Convert(char(10),OC.FechaEntrega,103),'')as FechaEntrega,
isNull(OC.ObsOrdenCompra,'')as ObsOrdenCompra,
U.IDUsuario,
Isnull(U.UsuarioNombres+' '+UsuarioApellidoPaterno,'')as [Usuario],
Case Isnull(OC.EstadoOrdenCompra,'')
When 'A' then 'Activo'
When 'I' then 'Inactivo'
End as EstadoOrdenCompra
From OrdenCompraTren OCT Inner Join OrdenCompra OC on(OCT.IDOrdenCompra=OC.IDOrdenCompra)
Inner Join ServicioTren ST on(OCT.IDServicioTren=ST.IDServicioTren)
Inner Join FileCabecera FC on(OCT.IDFile=FC.IDFile)
Left Outer Join TipoMoneda TM on(OC.IDTipoMoneda=TM.IDTipoMoneda)
Left Outer Join Usuario U on(OC.IDUsuario=U.IDUsuario)
Where
(OCT.IDOrdenCompraTren=@IDOrdenCompraTren or @IDOrdenCompraTren IS NULL)
And (OCT.IDOrdenCompra=@IDOrdenCompra or @IDOrdenCompra IS NULL)
And (OCT.IDServicioTren=4)
And (OCT.IDFile=@IDFile or @IDFile IS NULL)
And (CONVERT(Smalldatetime,CONVERT(Varchar,OC.FechaEmision,103),103)>=CONVERT(Smalldatetime,CONVERT(Varchar,@FechaEmisionIni,103),103) or CONVERT(Smalldatetime,CONVERT(Varchar,@FechaEmisionIni,103),103) IS NULL)
And (CONVERT(Smalldatetime,CONVERT(Varchar,OC.FechaEmision,103),103)<=CONVERT(Smalldatetime,CONVERT(Varchar,@FechaEmisionFin,103),103) or CONVERT(Smalldatetime,CONVERT(Varchar,@FechaEmisionFin,103),103) IS NULL)
And (OCT.CodigoReservaTren=@CodigoReservaTren or @CodigoReservaTren IS NULL)
And (OCT.NroOpeDep=@NroOpeDep or @NroOpeDep IS NULL)
And (OC.IdTipoMoneda=@IDTipoMoneda or @IDTipoMoneda IS NULL)
And (OCT.EstadoTipSer=@EstadoTipSer or @EstadoTipSer is null)
And (OCT.EstadoDetTren=@EstadoDetTren or @EstadoDetTren is null)

Ricardo Castro

19/4/2010
Manejo del sql
Deseo saber Cual es la forma correcta del uso de la sintaxis, cuando se desea buscar dentro de un grupo de registros indexados que estan ordenados por numeros o matriculas y deseamos ver los que comiencen con el numero 5 y que solo se muestren estos.. Sabemos que para buscar un nombre podemos usar %pepe% o *pepe*

Ricardo Castro

19/4/2010
Buscando un registro en la base de datos Sql
Yo se que para buscar un nombre especifico dentro de un grupo de registro usando el Sql se puede lograr usando la sentencia Like acompañada del signo de % o el signo de * dependiendo de la version de la Sql. Mi pregunta es que sentencia debo usar cuando se trata de buscar dentro de un grupo de numero a un numero especifico. en el modo de buscar nombre se utiliza Like %p%, cual es la forma correcta para buscar un numero especifico dentro de una base de datos grande

Golveron

20/4/2010
Excelente artículo... excelentes comentarios
Señores, agradecido... estaba con un problema de una consulta que involucraba varias tablas. No hice el diseño de la BD yo lamentablemente, pero leyendo éste artículo y gracias a algunos conocimientos anteriores, revisé la bd y me di cuenta que los algunos campos relacionados a la consulta no estaban indexados. Luego de indexarlos reduje el tiempo de espera de una forma suficientemente considerable.
Gracias y sigan subiendo éstos artículos tan útiles.

Les saluda cordialmente,

Golveron.
josbolivar@gmail.com

Tomás

06/5/2010
Union all vs outer joins
Hola a todos.

Tengo que realizar una consulta que me devuelva una serie de resultados determinados y la forma de construir dicha consulta puedo realizarla mediante un outer join o mediante el usa de "union all". A pesar de que sé que los conceptos de una y otra claúsula son diferentes, me gustaría saber qué es más efectivo: usar outer joins o usar "union all".

Muchas gracias por vuestar atención

jhonny666

16/5/2010
Oracle
Donde puedo conseguir informacion de la buenas practicas de Sql..me Pueden ayudar por favor ....

Los index no se pueden poner por que uno desea...sino deacuerdo a los Insert, Update, Select de ti consulta..

La sentencia Union all es mas costosa que la Union.....por traer datos duplicados.

La sentencia OR es la mas peligrosa de todas ..eviten utilizar.

Los INNER JOIN, LETHG JOIN no afenta en mucho la sentencia.

braulioss6

01/6/2010
Respondiendo a Ricardo Castro
Si conoces el numero que deseas buscar dentro de la base de datos puedes utilizar =
Por ejemplo. where nombre_campo = 34887 o puede ser usando like '%348' esto te traera todos los numeros que empiezen con 348. (Puedes usar like para buscar numeros o palabras)

good look

braulioss6

01/6/2010
excelente articulo
Muy buen articulo... Muchas gracias.
En addicion, sabemos que los outer joins son mas rapidos pero pueden resultar confusos o incomodos a la hora de escribir nuestro codigo cuando trabajamos con gran cantidad de tablas.... He trabajado con muchas tablas y para manipularlas he realizado el join en el where donde tengo mejor manejo a la hora de buscar cualquier error o modificacion.

Andrés Reyes L.

07/7/2010
Indices en las tablas de Sql
Es importante la generacion de indices en las tablas, ayudan a que las consultas sean rapidas

Carlos Fuenmayor

05/11/2010
Excelente articulo
Lo considerare para el análisis que query que estoy haciendo.
saludos
CCas-Vzla

JUAN

17/11/2010
OPTIMIZACION DE CONSULTAS
Amigo sabe donde puedo encontrar informacion de que tipo de indices usa el optimizador de oracle para variables numericas varchar y date gracias

Rene

18/1/2011
AYUDA.
COMO PODRIAN OPTIMIZAR ESTA CONSULTA.... PARA QUE EL TIEMPO DE ENTREGA SEA MUCHO MENOR.

select

to_char(a.fecha-6/24, 'yyyymmdd') as fecha,
a.pais as pais,
a.rnc as rnc,
substr(a.SECTOR,1,6) as celda,
a.sector as sector,
sum(a.var7) as intentos_RRC_PS,
sum(a.var25) as intentos_Voz_CS,
sum(a.var28 - a.var46 - (a.var50 - a.var53)) as intentos_LlamadaR99,
sum(a.var46 - (a.var51 - a.var52)) as intentos_LlamadaHSDPA,
sum(a.var85) as intentos_LlamadaHSUPA,
sum(h.var45) as Intentos_SHO_HSDPA,
sum(a.var8) as exitos_RRC_PS,
sum(a.var30) as exitos_Voz_CS,
sum(a.var33 - a.var47) as exitos_LlamadaR99,
sum(a.var47) as exitos_LlamadaHSDPA,
sum(a.var86) as exitos_LlamadaHSUPA,
sum(h.var46) as Exitos_SHO_HSDPA,
case when sum(a.var7 - a.var8) < 0 then 0 else sum(a.var7 - a.var8) end as Fallas_RRC_PS,
case when sum(a.var25 - a.var30) < 0 then 0 else sum(a.var25 - a.var30) end as Fallas_Voz_CS,
case when sum((a.var28 - a.var46 - (a.var50 - a.var53)) - (a.var33 - a.var47)) < 0 then 0 else sum((a.var28 - a.var46 - (a.var50 - a.var53)) - (a.var33 - a.var47)) end as Fallas_LlamadaR99,
case when sum((a.var46 - (a.var51 - a.var52)) - (a.var47)) < 0 then 0 else sum((a.var46 - (a.var51 - a.var52)) - (a.var47)) end as Fallas_LlamadaHSPDA,
case when sum((a.var85) - (a.var86)) < 0 then 0 else sum((a.var85) - (a.var86)) end Fallas_LlamadaHSUPA,
case when sum(h.var45 - h.var46) < 0 then 0 else sum(h.var45 - h.var46) end as Fallas_SHO_HSDPA,
sum(u.var3 + h.var115) as Rechazo_Conges_RRC_PS,
sum(a.var22 + h.var101) as Rechazo_Conges_Voz_CS,
case when sum(a.var24 - a.var54 + h.var105) < 0 then 0 else sum(a.var24 - a.var54 + h.var105) end as Rechazo_Conges_LlamadaR99,
sum(a.var54 + h.var106) as Rechazo_Conges_LlamadaHSDPA,
sum(a.var93) as Rechazo_Conges_LlamadaHSUPA,
sum(l.var14 + l.var10) as CaidasRRC,
sum(d.var37 - d.var49 - l.var73) as caidasR99,
sum(d.var49) as caidasHSDPA,
sum(a.var87) as caidasHSUPA,
sum(l.var13 + l.var8) as liberacionRRC,
sum(d.var35 - l.var72 - d.var48 + d.var167 + l.var69 + l.var60) as liberacionR99,
sum(d.var48 + d.var166 + d.var173) as liberacionHSDPA,
round(sum(decode(a.var15,0,0,a.var16/a.var15) + decode(u.var4,0,0,u.var8/u.var4) + decode(u.var7,0,0,u.var11/u.var7) + decode(u.var6,0,0,u.var10/u.var6) + decode(u.var5,0,0,u.var9/u.var5) + decode(v.var11,0,0,v.var16/v.var11)),0) as Trafico_Voz_CS,
round((sum((u.var1 + v.var4 + v.var1 + v.var3 + v.var5 + v.var2)*1000/8)/1000000),2) as TraficoR99_DL_MBYTES,
round((sum((u.var12 + v.var20 + v.var17 + v.var19 + v.var21 + v.var18)*1000/8)/1000000),2) as TraficoR99_UL_MBYTES,
round((sum((u.var2)*1000/8)/1000000),2) as TraficoHSDPA_MBYTES,
round((sum((k.var149)*1000/8)/1000000),2) as TraficoHSUPA_MBYTES,
case when (decode(sum(d.var7 - d.var121),0,0,sum(d.var8)/sum(d.var7 - d.var121)))*(decode(sum(d.var178 + d.var179),0,0,sum(d.var178)/sum(d.var178 + d.var179)))*(decode(sum(d.var122),0,0,sum(d.var123)/sum(d.var122))) > 1 then '100%' else round((decode(sum(d.var7 - d.var121),0,0,sum(d.var8)/sum(d.var7 - d.var121)))*(decode(sum(d.var178 + d.var179),0,0,sum(d.var178)/sum(d.var178 + d.var179)))*(decode(sum(d.var122),0,0,sum(d.var123)/sum(d.var122)))*100,2)||'%' end as accesibilityR99,
case when (decode(sum(d.var7 - d.var121),0,0,sum(d.var8)/sum(d.var7 - d.var121)))*(decode(sum(d.var178 + d.var179),0,0,sum(d.var178)/sum(d.var178 + d.var179)))*(decode(sum(d.var46),0,0,sum(d.var47)/sum(d.var46))) > 1 then '100%' else round((decode(sum(d.var7 - d.var121),0,0,sum(d.var8)/sum(d.var7 - d.var121)))*(decode(sum(d.var178 + d.var179),0,0,sum(d.var178)/sum(d.var178 + d.var179)))*(decode(sum(d.var46),0,0,sum(d.var47)/sum(d.var46)))*100,2)||'%' end as accesibilityHSPDA,
case when (decode(sum(d.var7 - d.var121),0,0,sum(d.var8)/sum(d.var7 - d.var121)))*(decode(sum(d.var178 + d.var179),0,0,sum(d.var178)/sum(d.var178 + d.var179)))*(decode(sum(d.var28),0,0,sum(d.var33)/sum(d.var28))) > 1 then '100%' else round((decode(sum(d.var7 - d.var121),0,0,sum(d.var8)/sum(d.var7 - d.var121)))*(decode(sum(d.var178 + d.var179),0,0,sum(d.var178)/sum(d.var178 + d.var179)))*(decode(sum(d.var28),0,0,sum(d.var33)/sum(d.var28)))*100,2)||'%' end as accesibilityRAB,
round((decode(sum(d.var35 - l.var72 + d.var37 - l.var73 - d.var48 - d.var49 + d.var167 + l.var69 + l.var60),0,0,sum(d.var37 - l.var73 - d.var49)/sum(d.var35 - l.var72 + d.var37 - l.var73 - d.var48 - d.var49 + d.var167 + l.var69 + l.var60)))*100,2)||'%' as reteinabilityR99,
round((decode(sum(d.var48 + d.var49 + d.var166 + d.var173),0,0,sum(d.var49)/sum(d.var48 + d.var49 + d.var166 + d.var173)))*100,2)||'%' as reteinabilityHSPDA,
round(sum(decode(l.var128,0,0,(l.var126/l.var128))),0) as DL_ChanCode_Usage_Av,
round((case when sum(decode(d.var10,0,0,(d.var11/d.var10))) < 0 then 0 else sum(decode(d.var10,0,0,(d.var11/d.var10))) end),0) as Usuarios_Promedio_Voz,
round(sum(decode(d.var83,0,0,(d.var84/d.var83)) + d.var69 + d.var68),0) as Usuarios_Promedio_R99,
round(sum(decode(l.var47,0,0,(l.var48/l.var47))),0) as Usuarios_Promedio_HSDPA,
round(sum(decode(l.var79,0,0,(l.var80/l.var79))),0) as Usuarios_Promedio_EUL,
sum(a.var18) as T_Fuera_Serv_Auto_Celda
from
umtstabla1 a, umtstabla3 c, umtstabla2 d, umtstabla8 h, umtstabla11 k, umtstabla12 l, umtstabla21 u, umtstabla22 v
where to_char(a.fecha-6/24, 'yyyymmdd') = to_char(sysdate-1, 'yyyymmdd')
and a.fecha = c.fecha
and c.fecha = d.fecha
and d.fecha = h.fecha
and h.fecha = k.fecha
and k.fecha = l.fecha
and l.fecha = u.fecha
and u.fecha = v.fecha
and a.rnc = c.rnc
and c.rnc = d.rnc
and d.rnc = h.rnc
and h.rnc = k.rnc
and k.rnc = l.rnc
and l.rnc = u.rnc
and u.rnc = v.rnc
and a.sector = c.sector
and c.sector = d.sector
and d.sector = h.sector
and h.sector = k.sector
and k.sector = l.sector
and l.sector = u.sector
and u.sector = v.sector
and a.pais = 'NICARAGUA'
group by to_char(a.fecha-6/24, 'yyyymmdd'), a.pais, a.rnc, a.sector
order by a.sector asc, to_char(a.fecha-6/24, 'yyyymmdd') asc

Carlos J

10/3/2011
Forzar indices en sql server
En algunas ocasiones el motor de base de datos no tima el índice correcto al realizar una consulta, en estos casos es necesario forzar la consulta para que tome el índice adecuado.

En esta dirección Web, hay un articulo que les puede ser muy útil

http://www.sqlevolution.com/forzar-indices-en-sql-server/

Para hacer seguimineto a la consulta y poder detectar si esta no esta tomando los indices esperados, podemos apoyarnos de la herramienta "Mostrar plán de ejecución estimado" de SQL Server

RAFA

21/3/2011
Que puedo optimizar
Este procedure me demora 5 horas en ejecutarse por favor me podrian decir por favor que puedo optimizar??

CREATE OR REPLACE PROCEDURE "STORE_PROCEDURE"
( ISID_SESS TWRUBR_ERBQ.ID_SESS%TYPE, --'99999999'
ISCO_EMPR TCGUIA.CO_EMPR%TYPE, --01
ISCO_UNID TCGUIA.CO_UNID%TYPE,--001
ISTI_VEND TMVEND.TI_VEND%TYPE,--NULL
ISCO_VEND TMVEND.CO_VEND%TYPE,--NULL
ISTI_CLIE TMCLIE.TI_CLIE%TYPE,--NULL
ISCO_CLIE TMCLIE.CO_CLIE%TYPE,--NULL
ISCO_COLE TMCOLE.CO_COLE%TYPE,--NULL
IDFE_INIC TCDOCU_CLIE.FE_DOCU%TYPE,--'01-01-2008'
IDFE_FINA TCDOCU_CLIE.FE_DOCU%TYPE,--'07-04-2008'
ISST_VENT_DIRE TTTIPO_FACT_REPO.ST_VENT_DIRE%TYPE,--'X'
ISST_CONS TTTIPO_FACT_REPO.ST_CONS%TYPE,--'S'
ISST_PROM TTTIPO_FACT_REPO.ST_PROM%TYPE,--'X'
ISST_OTRO TTTIPO_FACT_REPO.ST_OTRO%TYPE,--'X'
ISSE_SELE CHAR,--'N'
INFA_CAMB NUMBER,--2.62
ISCO_USUA TRINFO_GRUP.CO_GRUP%TYPE,--'SISTEMAS'
ISCO_SIST TTTIPO_INF1.CO_SIST%TYPE --'OFIVENT'
)
As
--Variables Cursor
CSCO_UNID TWREPO_VENT.CO_UNID%TYPE;
CSCO_VEND TWREPO_VENT.CO_VEND%TYPE;
CSCO_COLE TWREPO_VENT.CO_COLE%TYPE;
CSCO_CLIE TWREPO_VENT.CO_CLIE%TYPE;
CSCO_ITEM TWREPO_VENT.CO_ITEM%TYPE;
--Variables Locales
VSTI_DIRE_FACT TMPARA_VENT.TI_DIRE_FACT%TYPE;
VSTI_DOCU_TICK TMPARA_VENT.TI_DOCU_TICK%TYPE;
VSTI_DOCU_FACT TMPARA_VENT.TI_DOCU_FACT%TYPE;
VSTI_DOCU_BOLE TMPARA_VENT.TI_DOCU_BOLE%TYPE;
VSTI_DOCU_NCRE TMPARA_VENT.TI_DOCU_NCRE%TYPE;
VSCO_MONE_NACI TMPARA_VENT.CO_MONE_NACI%TYPE;
VSCO_MONE_EXTR TMPARA_VENT.CO_MONE_EXTR%TYPE;
---
VSCO_UNID TWREPO_VENT.CO_UNID%TYPE;
VSCO_VEND TWREPO_VENT.CO_VEND%TYPE;
VSNO_VEND TWREPO_VENT.NO_VEND%TYPE;
VSTI_VEND TWREPO_VENT.TI_VEND%TYPE;
VSDE_TIPO_VEND TWREPO_VENT.DE_TIPO_VEND%TYPE;
VSCO_COLE TWREPO_VENT.CO_COLE%TYPE;
VSNO_COLE TWREPO_VENT.NO_COLE%TYPE;
VSCO_CLIE TWREPO_VENT.CO_CLIE%TYPE;
VSNO_CLIE TWREPO_VENT.NO_CLIE%TYPE;
VSTI_CLIE TWREPO_VENT.TI_CLIE%TYPE;
VSDE_TIPO_CLIE TWREPO_VENT.DE_TIPO_CLIE%TYPE;
VSCO_ITEM TWREPO_VENT.CO_ITEM%TYPE;
VSDE_ITEM TWREPO_VENT.DE_ITEM%TYPE;
VSDE_ITEM_LARG TWREPO_VENT.DE_ITEM_LARG%TYPE;
VSCO_RUBR TWREPO_VENT.CO_RUBR%TYPE;
VSDE_RUBR TWREPO_VENT.DE_RUBR%TYPE;
VSCO_FAMI TWREPO_VENT.CO_FAMI%TYPE;
VSDE_FAMI TWREPO_VENT.DE_FAMI%TYPE;
VSCO_SFAM TWREPO_VENT.CO_SFAM%TYPE;
VSDE_SFAM TWREPO_VENT.DE_SFAM%TYPE;
VNCA_INGR_GUIA TWREPO_VENT.CA_INGR_GUIA%TYPE;
VNMO_INGR_GUIA_DOLA TWREPO_VENT.MO_INGR_GUIA_DOLA%TYPE;
VNMO_INGR_GUIA_SOLE TWREPO_VENT.MO_INGR_GUIA_SOLE%TYPE;
VNCA_INGR_OTRO TWREPO_VENT.CA_INGR_OTRO%TYPE;
VNMO_INGR_OTRO_DOLA TWREPO_VENT.MO_INGR_OTRO_DOLA%TYPE;
VNMO_INGR_OTRO_SOLE TWREPO_VENT.MO_INGR_OTRO_SOLE%TYPE;
VNCA_DEVS TWREPO_VENT.CA_NCRE%TYPE;
VNMO_DEVS_DOLA TWREPO_VENT.MO_NCRE_DOLA%TYPE;
VNMO_DEVS_SOLE TWREPO_VENT.MO_NCRE_SOLE%TYPE;
VNCA_SALI_OTRO TWREPO_VENT.CA_SALI_OTRO%TYPE;
VNMO_SALI_OTRO_DOLA TWREPO_VENT.MO_SALI_OTRO_DOLA%TYPE;
VNMO_SALI_OTRO_SOLE TWREPO_VENT.MO_SALI_OTRO_SOLE%TYPE;
VNCA_FACT TWREPO_VENT.CA_FACT%TYPE;
VNMO_FACT_DOLA TWREPO_VENT.MO_FACT_DOLA%TYPE;
VNMO_FACT_SOLE TWREPO_VENT.MO_FACT_SOLE%TYPE;
VNCA_DEVO_NCRE TWREPO_VENT.CA_DEVO_NCRE%TYPE;
VNCA_DEVO_NCRE2 TWREPO_VENT.CA_DEVO_NCRE%TYPE;
VNMO_DEVO_NCRE_DOLA TWREPO_VENT.MO_DEVO_NCRE_DOLA%TYPE;
VNMO_DEVO_NCRE_SOLE TWREPO_VENT.MO_DEVO_NCRE_SOLE%TYPE;
VSID NUMBER;
VSCO_MONE TMITEM.CO_MONE%TYPE;
VNCA_INGR TWREPO_VENT.CA_INGR_OTRO%TYPE;
VNCA_SALI TWREPO_VENT.CA_SALI_OTRO%TYPE;
VNCA_INGR_REUB TWREPO_VENT.CA_INGR_OTRO%TYPE;
VNCA_SALI_REUB TWREPO_VENT.CA_SALI_OTRO%TYPE;
--CURSOR
CURSOR CU_SSP_TWREPO_VENT_I01_1 IS
SELECT T1.CO_UNID, T1.CO_VEND, T1.CO_COLE, T1.CO_CLIE, T1.CO_ITEM,
NVL(T2.CA_INGR_GUIA, 0),
NVL(T2.MO_INGR_GUIA_DOLA, 0),
NVL(T2.MO_INGR_GUIA_SOLE, 0),
NVL(T3.CA_FACT, 0),
NVL(T3.MO_FACT_DOLA, 0),
NVL(T3.MO_FACT_SOLE, 0),
NVL(T3.CA_DEVO_NCRE, 0),
NVL(T3.MO_DEVO_NCRE_DOLA, 0),
NVL(T3.MO_DEVO_NCRE_SOLE, 0),
NVL(T4.CA_INGR,0),
NVL(T4.CA_DEVS,0),
NVL(T4.CA_DEVO_NCRE, 0),
NVL(T4.CA_SALI, 0),
NVL(T4.CA_INGR_OTRO, 0),
NVL(T4.CA_SALI_OTRO, 0)
/*
FROM OFIVENT.TWREPO_VENT_0001 T1,
OFIVENT.TWREPO_VENT_0002 T2,
OFIVENT.TWREPO_VENT_0003 T3,
OFIVENT.TWREPO_VENT_0004 T4
*/
FROM OFIVENT.TWREPO_VENT_0001 T1
LEFT JOIN OFIVENT.TWREPO_VENT_0002 T2 ON
( T1.CO_UNID = T2.CO_UNID
AND T1.CO_VEND = T2.CO_VEND
AND T1.CO_COLE = T2.CO_COLE
AND T1.CO_CLIE = T2.CO_CLIE
AND T1.CO_ITEM = T2.CO_ITEM
AND T1.ID_SESS = T2.ID_SESS)

LEFT JOIN OFIVENT.TWREPO_VENT_0003 T3 ON
( T1.CO_UNID = T3.CO_UNID
AND T1.CO_VEND = T3.CO_VEND
AND T1.CO_COLE = T3.CO_COLE
AND T1.CO_CLIE = T3.CO_CLIE
AND T1.CO_ITEM = T3.CO_ITEM
AND T1.ID_SESS = T3.ID_SESS)

LEFT JOIN OFIVENT.TWREPO_VENT_0004 T4 ON
( T1.CO_UNID = T4.CO_UNID
AND T1.CO_VEND = T4.CO_VEND
AND T1.CO_COLE = T4.CO_COLE
AND T1.CO_CLIE = T4.CO_CLIE
AND T1.CO_ITEM = T4.CO_ITEM
AND T1.ID_SESS = T4.ID_SESS)

WHERE T1.ID_SESS = ISID_SESS

-- AND ((T1.CO_COLE IS NOT NULL AND T2.CO_COLE IS NOT NULL AND (T1.CO_COLE = T2.CO_COLE)) OR (T2.CO_COLE IS NULL) OR (T1.CO_COLE IS NULL AND T2.CO_COLE IS NULL)
-- AND ((T1.CO_COLE IS NOT NULL AND T3.CO_COLE IS NOT NULL AND (T1.CO_COLE = T3.CO_COLE)) OR (T3.CO_COLE IS NULL) OR (T1.CO_COLE IS NULL AND T3.CO_COLE IS NULL))
-- AND ((T1.CO_COLE IS NOT NULL AND T4.CO_COLE IS NOT NULL AND (T1.CO_COLE = T4.CO_COLE)) OR (T4.CO_COLE IS NULL) OR (T1.CO_COLE IS NULL AND T4.CO_COLE IS NULL))
ORDER BY 1,4,5,2,3;

BEGIN


DELETE FROM OFIVENT.TWREPO_VENT_0001 WHERE ID_SESS = ISID_SESS;
-- COMMIT;

DELETE FROM OFIVENT.TWREPO_VENT_0002 WHERE ID_SESS = ISID_SESS;
-- COMMIT;

DELETE FROM OFIVENT.TWREPO_VENT_0003 WHERE ID_SESS = ISID_SESS;
--- COMMIT;

DELETE FROM OFIVENT.TWREPO_VENT_0004 WHERE ID_SESS = ISID_SESS;
-- COMMIT;

DELETE FROM OFIVENT.TWREPO_VENT_0005 WHERE ID_SESS = ISID_SESS;
-- COMMIT;

DELETE FROM OFIVENT.TWREPO_VENT WHERE ID_SESS = ISID_SESS;
COMMIT;

-- OBTIENE TIPO DIRECCION DEFAULT, TIPOS DE DOCUMENTOS --
BEGIN
SELECT TI_DIRE_FACT,
TI_DOCU_TICK,
TI_DOCU_FACT,
TI_DOCU_BOLE,
TI_DOCU_NCRE,
CO_MONE_NACI,
CO_MONE_EXTR
INTO VSTI_DIRE_FACT,
VSTI_DOCU_TICK,
VSTI_DOCU_FACT,
VSTI_DOCU_BOLE,
VSTI_DOCU_NCRE,
VSCO_MONE_NACI,
VSCO_MONE_EXTR
FROM TMPARA_VENT
WHERE CO_EMPR = ISCO_EMPR;
EXCEPTION WHEN NO_DATA_FOUND THEN
BEGIN
VSTI_DIRE_FACT := NULL;
VSTI_DOCU_TICK := 'TIK';
VSTI_DOCU_BOLE := 'BOL';
VSTI_DOCU_FACT := 'FAC';
VSTI_DOCU_NCRE := 'NCR';
VSCO_MONE_NACI := 'SOL';
VSCO_MONE_EXTR := 'DOL';
END;
END;
-- INSERTA EN LA TABLA TEMPORAL
INSERT /*+ APPEND */ INTO OFIVENT.TWREPO_VENT_0001
(CO_UNID, CO_VEND, CO_COLE, CO_CLIE, CO_ITEM, ID_SESS)
SELECT CO_UNID, CO_VEND, CO_COLE, CO_CLIE, CO_ITEM, ISID_SESS
FROM (
SELECT DISTINCT T1.CO_UNID, T1.CO_VEND, T1.CO_COLE, T1.CO_CLIE, T2.CO_ITEM
FROM TCGUIA T1 INNER JOIN TDGUIA T2 ON (
T2.CO_EMPR = T1.CO_EMPR
AND T2.CO_UNID = T1.CO_UNID
AND T2.NU_GUIA = T1.NU_GUIA)
INNER JOIN

--- FROM TCGUIA T1,
--- TDGUIA T2,
----cambiamos--------------
/*
(SELECT DISTINCT T31.CO_CLIE AS CO_CLIE
FROM TMCLIE T31 , TTUBIC_ALMA T32
WHERE T31.CO_EMPR = ISCO_EMPR
AND ((ISCO_CLIE IS NOT NULL AND T31.CO_CLIE = ISCO_CLIE) OR ISCO_CLIE IS NULL)
AND ((ISTI_CLIE IS NOT NULL AND T31.TI_CLIE = ISTI_CLIE) OR ISTI_CLIE IS NULL)
AND T32.CO_EMPR = T31.CO_EMPR
AND T32.CO_UBIC_ALMA = T31.CO_CLIE
AND ROWNUM>= 1) T3

*/
(SELECT DISTINCT T31.CO_CLIE AS CO_CLIE
FROM TMCLIE T31 , TTUBIC_ALMA T32
WHERE T31.CO_EMPR = ISCO_EMPR
AND ((ISCO_CLIE IS NOT NULL AND T31.CO_CLIE = ISCO_CLIE) OR ISCO_CLIE IS NULL)
AND ((ISTI_CLIE IS NOT NULL AND T31.TI_CLIE = ISTI_CLIE) OR ISTI_CLIE IS NULL)
AND T32.CO_EMPR = T31.CO_EMPR
AND T32.CO_UBIC_ALMA = T31.CO_CLIE
AND ROWNUM>= 1) T3 ON (
T3.CO_CLIE = T1.CO_CLIE)
/*
(SELECT CO_VEND
FROM TMVEND
WHERE CO_EMPR = ISCO_EMPR
AND (( ISCO_VEND IS NOT NULL AND CO_VEND = ISCO_VEND) OR ISCO_VEND IS NULL)
AND (( ISTI_VEND IS NOT NULL AND TI_VEND = ISTI_VEND) OR ISTI_VEND IS NULL)
AND ROWNUM>= 1) T4,

*/
INNER JOIN
(SELECT CO_VEND
FROM TMVEND
WHERE CO_EMPR = ISCO_EMPR
AND (( ISCO_VEND IS NOT NULL AND CO_VEND = ISCO_VEND) OR ISCO_VEND IS NULL)
AND (( ISTI_VEND IS NOT NULL AND TI_VEND = ISTI_VEND) OR ISTI_VEND IS NULL)
AND ROWNUM>= 1) T4 ON (
T4.CO_VEND = T1.CO_VEND)
INNER JOIN TTTIPO_FACT_REPO T5 ON
(
T5.CO_EMPR = T1.CO_EMPR
AND T5.TI_FACT = T1.TI_FACT)
INNER JOIN TMITEM T55 ON (
T55.CO_ITEM = T2.CO_ITEM
AND T55.CO_COR1 = T2.CO_COR1
AND T55.TI_PRES = T2.TI_PRES
AND T55.CO_COR2 = T2.CO_COR2)
LEFT JOIN TWRUBR_ERBQ T6 ON (
T55.CO_RUBR = T6.CO_RUBR)
LEFT JOIN TWITEM_ERBQ T7 ON (
T55.CO_ITEM = T7.CO_ITEM
AND T55.CO_COR1 = T7.CO_COR1
AND T55.TI_PRES = T7.TI_PRES
AND T55.CO_COR2 = T7.CO_COR2)

----- TTTIPO_FACT_REPO T5,
--- TMITEM T55,
---- TWRUBR_ERBQ T6,
--- TWITEM_ERBQ T7
WHERE T1.CO_EMPR = ISCO_EMPR
AND T1.FE_GUIA >= IDFE_INIC
AND T1.FE_GUIA <= IDFE_FINA
AND exists ( SELECT T43.CO_UNID
---FROM TTTIPO_INF1 T41, TRINFO_GRUP T42, TMUNID_VENT T43
FROM TTTIPO_INF1 T41 INNER JOIN TRINFO_GRUP T42 ON (
T42.CO_EMPR = T41.CO_EMPR
AND T42.TI_INF1 = T41.TI_INF1)
INNER JOIN TMUNID_VENT T43 ON (
T43.CO_EMPR = T42.CO_EMPR
AND T43.CO_UNID = T42.TI_INF2)
WHERE T41.CO_EMPR = ISCO_EMPR
AND T41.CO_SIST = ISCO_SIST
AND T42.CO_GRUP = ISCO_USUA
AND ((ISCO_UNID IS NOT NULL AND T43.CO_UNID = ISCO_UNID) OR ISCO_UNID IS NULL )
AND ROWNUM >= 1)
AND ((ISCO_COLE IS NOT NULL AND T1.CO_COLE = ISCO_COLE) OR ISCO_COLE IS NULL)
AND T1.ST_DOCU != 'ANU'
AND T5.ST_CONS = ISST_CONS
--- AND T6.ID_SESS (+) = ISID_SESS
AND T6.ID_SESS = ISID_SESS
--- AND T7.ID_SESS (+) = ISID_SESS
AND T7.ID_SESS = ISID_SESS
AND ((ISSE_SELE = 'A' AND T7.CO_ITEM = T55.CO_ITEM
AND T7.ID_SESS = ISID_SESS)
OR
(ISSE_SELE = 'R' AND T6.CO_RUBR = T55.CO_RUBR
AND T6.ID_SESS = ISID_SESS)
OR
(ISSE_SELE = 'F' AND T6.CO_RUBR = T55.CO_RUBR
AND T6.CO_FAMI = T55.CO_FAMI
AND T6.ID_SESS = ISID_SESS)
OR
(ISSE_SELE = 'S' AND T6.CO_RUBR = T55.CO_RUBR
AND T6.CO_FAMI = T55.CO_FAMI
AND T6.CO_SFAM = T55.CO_SFAM
AND T6.ID_SESS = ISID_SESS)
OR ISSE_SELE = 'N')

UNION
SELECT DISTINCT T1.CO_UNID, T1.CO_VEND, T1.CO_COLE, T1.CO_CLIE, T2.CO_ITEM
---FROM TCDOCU_CLIE T1,
FROM TCDOCU_CLIE T1 INNER JOIN TDDOCU_CLIE T2 ON
(
T2.CO_EMPR = T1.CO_EMPR
AND T2.CO_UNID = T1.CO_UNID
AND T2.TI_DOCU = T1.TI_DOCU
AND T2.NU_DOCU = T1.NU_DOCU)
INNER JOIN
--- TDDOCU_CLIE T2,
(SELECT DISTINCT T31.CO_CLIE AS CO_CLIE
FROM TMCLIE T31 --, TTUBIC_ALMA T32
WHERE T31.CO_EMPR = ISCO_EMPR
AND ((ISCO_CLIE IS NOT NULL AND T31.CO_CLIE = ISCO_CLIE) OR ISCO_CLIE IS NULL)
AND ((ISTI_CLIE IS NOT NULL AND T31.TI_CLIE = ISTI_CLIE) OR ISTI_CLIE IS NULL)
AND ROWNUM>= 1) T3 ON (
T3.CO_CLIE = T1.CO_CLIE)
INNER JOIN
(SELECT CO_VEND
FROM TMVEND
WHERE CO_EMPR = ISCO_EMPR
AND (( ISCO_VEND IS NOT NULL AND CO_VEND = ISCO_VEND) OR ISCO_VEND IS NULL)
AND (( ISTI_VEND IS NOT NULL AND TI_VEND = ISTI_VEND) OR ISTI_VEND IS NULL)
AND ROWNUM>= 1) T4 ON (
T4.CO_VEND = T1.CO_VEND)

INNER JOIN TTTIPO_FACT_REPO T5 ON (
T5.CO_EMPR = T1.CO_EMPR
AND T5.TI_FACT = T1.TI_FACT)
INNER JOIN TMITEM T55 ON (
T55.CO_ITEM = T2.CO_ITEM
AND T55.CO_COR1 = T2.CO_COR1
AND T55.TI_PRES = T2.TI_PRES
AND T55.CO_COR2 = T2.CO_COR2)
LEFT JOIN TWRUBR_ERBQ T6 ON (
T55.CO_RUBR = T6.CO_RUBR)
LEFT JOIN TWITEM_ERBQ T7 ON (
T55.CO_ITEM = T7.CO_ITEM
AND T55.CO_COR1 = T7.CO_COR1
AND T55.TI_PRES = T7.TI_PRES
AND T55.CO_COR2 = T7.CO_COR2
AND ISID_SESS= T7.ID_SESS )

--- TTTIPO_FACT_REPO T5,
---- TMITEM T55,
--- TWRUBR_ERBQ T6,
-- TWITEM_ERBQ T7
WHERE T1.CO_EMPR = ISCO_EMPR
AND T1.FE_DOCU >= IDFE_INIC
AND T1.FE_DOCU <= IDFE_FINA
AND exists ( SELECT T43.CO_UNID
---- FROM TTTIPO_INF1 T41, TRINFO_GRUP T42, TMUNID_VENT T43
FROM TTTIPO_INF1 T41 INNER JOIN TRINFO_GRUP T42 ON (
T42.CO_EMPR = T41.CO_EMPR
AND T42.TI_INF1 = T41.TI_INF1)
INNER JOIN TMUNID_VENT T43 ON (
T43.CO_EMPR = T42.CO_EMPR
AND T43.CO_UNID = T42.TI_INF2 )
WHERE T41.CO_EMPR = ISCO_EMPR
AND T41.CO_SIST = ISCO_SIST
AND T42.CO_GRUP = ISCO_USUA
AND ((ISCO_UNID IS NOT NULL AND T43.CO_UNID = ISCO_UNID) OR ISCO_UNID IS NULL )
AND ROWNUM>= 1)
AND ((ISCO_COLE IS NOT NULL AND T1.CO_COLE = ISCO_COLE) OR ISCO_COLE IS NULL)
AND T1.CO_ESTA_DOCU != 'ANU'
AND T1.TI_DOCU IN (VSTI_DOCU_TICK, VSTI_DOCU_FACT, VSTI_DOCU_BOLE, VSTI_DOCU_NCRE)
AND (T5.ST_CONS = ISST_CONS OR T5.ST_VENT_DIRE = ISST_VENT_DIRE OR T5.ST_PROM = ISST_PROM OR T5.ST_OTRO = ISST_OTRO)
--- AND T6.ID_SESS (+) = ISID_SESS
--- AND ISID_SESS= T7.ID_SESS (+)
AND ((ISSE_SELE = 'A' AND T7.CO_ITEM = T55.CO_ITEM
AND T7.ID_SESS = ISID_SESS)
OR
(ISSE_SELE = 'R' AND T6.CO_RUBR = T55.CO_RUBR
AND T6.ID_SESS = ISID_SESS)
OR
(ISSE_SELE = 'F' AND T6.CO_RUBR = T55.CO_RUBR
AND T6.CO_FAMI = T55.CO_FAMI
AND T6.ID_SESS = ISID_SESS)
OR
(ISSE_SELE = 'S' AND T6.CO_RUBR = T55.CO_RUBR
AND T6.CO_FAMI = T55.CO_FAMI
AND T6.CO_SFAM = T55.CO_SFAM
AND T6.ID_SESS = ISID_SESS)
OR ISSE_SELE = 'N'));
COMMIT;
----- EXECUTE IMMEDIATE 'ANALYZE TABLE OFIVENT.TWREPO_VENT_0001 ESTIMATE STATISTICS';
--97 SEGUNDOS (19708 REGISTROS)
INSERT /*+ APPEND */ INTO OFIVENT.TWREPO_VENT_0002
( CO_UNID, CO_VEND, CO_COLE, CO_CLIE, CO_ITEM, CA_INGR_GUIA, MO_INGR_GUIA_DOLA, MO_INGR_GUIA_SOLE, ID_SESS)
SELECT TT.CO_UNID, TT.CO_VEND, TT.CO_COLE, TT.CO_CLIE, TT.CO_ITEM,
NVL(SUM(T2.CA_GUIA),0) AS CA_INGR_GUIA,
ROUND(NVL(SUM(T2.CA_GUIA * T2.PR_VENT / POWER(T1.FA_CAMB, INSTR(T1.CO_MONE, VSCO_MONE_NACI))),0),2) AS MO_INGR_GUIA_DOLA,
ROUND(NVL(SUM(T2.CA_GUIA * T2.PR_VENT * POWER(T1.FA_CAMB, INSTR(T1.CO_MONE, VSCO_MONE_EXTR))),0),2) AS MO_INGR_GUIA_SOLE,
MAX(TT.ID_SESS)
---- FROM TCGUIA T1, TDGUIA T2, TTTIPO_FACT_REPO T3, OFIVENT.TWREPO_VENT_0001 TT
FROM TCGUIA T1 INNER JOIN TDGUIA T2 ON
(
T2.CO_EMPR = T1.CO_EMPR
AND T2.CO_UNID = T1.CO_UNID
AND T2.NU_GUIA = T1.NU_GUIA)
INNER JOIN TTTIPO_FACT_REPO T3 ON
(
T3.CO_EMPR = T1.CO_EMPR
AND T3.TI_FACT = T1.TI_FACT)
INNER JOIN OFIVENT.TWREPO_VENT_0001 TT ON
(
T1.CO_UNID = TT.CO_UNID
AND T1.CO_CLIE = TT.CO_CLIE
AND T1.CO_VEND = TT.CO_VEND
AND T2.CO_ITEM = TT.CO_ITEM)
WHERE T1.CO_EMPR = ISCO_EMPR
AND TT.ID_SESS = ISID_SESS
AND T1.ST_DOCU != 'ANU'
AND T1.FE_GUIA >= IDFE_INIC
AND T1.FE_GUIA <= IDFE_FINA
AND T3.ST_CONS = ISST_CONS
AND ((TT.CO_COLE IS NOT NULL AND T1.CO_COLE = TT.CO_COLE) OR TT.CO_COLE IS NULL)
GROUP BY TT.CO_UNID, TT.CO_VEND, TT.CO_COLE, TT.CO_CLIE, TT.CO_ITEM;
---COMMIT;
----EXECUTE IMMEDIATE 'ANALYZE TABLE OFIVENT.TWREPO_VENT_0002 ESTIMATE STATISTICS';
-- 42 SEGUNDOS
INSERT /*+ APPEND */ INTO OFIVENT.TWREPO_VENT_0003
(CO_UNID, CO_VEND, CO_COLE, CO_CLIE, CO_ITEM, CA_FACT, MO_FACT_DOLA, MO_FACT_SOLE, CA_DEVO_NCRE, MO_DEVO_NCRE_DOLA, MO_DEVO_NCRE_SOLE, ID_SESS)
SELECT V.CO_UNID, V.CO_VEND, V.CO_COLE, V.CO_CLIE, V.CO_ITEM,
NVL(SUM(CASE WHEN V.TI_DOCU IN (VSTI_DOCU_TICK, VSTI_DOCU_FACT, VSTI_DOCU_BOLE)
THEN V.MTO
ELSE 0 END), 0),
NVL(SUM(CASE WHEN V.TI_DOCU IN (VSTI_DOCU_TICK, VSTI_DOCU_FACT, VSTI_DOCU_BOLE)
THEN V.MTO_DOL
ELSE 0 END), 0),
NVL(SUM(CASE WHEN V.TI_DOCU IN (VSTI_DOCU_TICK, VSTI_DOCU_FACT, VSTI_DOCU_BOLE)
THEN V.MTO_SOL
ELSE 0 END), 0),
NVL(SUM(CASE WHEN V.TI_DOCU IN (VSTI_DOCU_NCRE)
THEN V.MTO
ELSE 0 END), 0),
NVL(SUM(CASE WHEN V.TI_DOCU IN (VSTI_DOCU_NCRE)
THEN V.MTO_DOL
ELSE 0 END), 0),
NVL(SUM(CASE WHEN V.TI_DOCU IN (VSTI_DOCU_NCRE)
THEN V.MTO_SOL
ELSE 0 END), 0),
MAX(V.ID_SESS)
FROM (SELECT TT.CO_UNID, TT.CO_VEND, TT.CO_COLE, TT.CO_CLIE, TT.CO_ITEM, T1.TI_DOCU, NVL(SUM(T2.CA_DOCU),0) MTO,
ROUND(NVL(SUM(T2.CA_DOCU * T2.PR_VENT / POWER(T1.FA_CAMB, INSTR(T1.CO_MONE, VSCO_MONE_NACI))),0),2) MTO_DOL,
ROUND(NVL(SUM(T2.CA_DOCU * T2.PR_VENT * POWER(T1.FA_CAMB, INSTR(T1.CO_MONE, VSCO_MONE_EXTR))),0),2) MTO_SOL,
MAX(TT.ID_SESS) ID_SESS
--- FROM OFIVENT.TWREPO_VENT_0001 TT, TCDOCU_CLIE T1, TDDOCU_CLIE T2, TTTIPO_FACT_REPO T3
FROM TCDOCU_CLIE T1 INNER JOIN TDDOCU_CLIE T2 ON
(
T2.CO_EMPR = T1.CO_EMPR
AND T2.CO_UNID = T1.CO_UNID
AND T2.TI_DOCU = T1.TI_DOCU
AND T2.NU_DOCU = T1.NU_DOCU )
INNER JOIN TTTIPO_FACT_REPO T3 on
(
T3.CO_EMPR = T1.CO_EMPR
AND T3.TI_FACT = T1.TI_FACT)
INNER JOIN OFIVENT.TWREPO_VENT_0001 TT on
(
T1.CO_UNID = TT.CO_UNID
AND T1.CO_CLIE = TT.CO_CLIE
AND T1.CO_VEND = TT.CO_VEND
AND T2.CO_ITEM = TT.CO_ITEM)
WHERE T1.CO_EMPR = ISCO_EMPR
AND TT.ID_SESS = ISID_SESS
AND T1.CO_ESTA_DOCU != 'ANU'
AND ((TT.CO_COLE IS NOT NULL AND T1.CO_COLE = TT.CO_COLE) OR TT.CO_COLE IS NULL)
AND T1.FE_DOCU >= IDFE_INIC
AND T1.FE_DOCU <= IDFE_FINA
AND T1.TI_DOCU IN (VSTI_DOCU_TICK, VSTI_DOCU_FACT, VSTI_DOCU_BOLE, VSTI_DOCU_NCRE)
AND ((TT.CO_COLE IS NOT NULL AND T1.CO_COLE = TT.CO_COLE) OR TT.CO_COLE IS NULL)
AND (T3.ST_CONS = ISST_CONS OR T3.ST_VENT_DIRE = ISST_VENT_DIRE OR T3.ST_PROM = ISST_PROM OR T3.ST_OTRO = ISST_OTRO)
GROUP BY TT.CO_UNID, TT.CO_VEND, TT.CO_COLE, TT.CO_CLIE, TT.CO_ITEM, T1.TI_DOCU) V
GROUP BY V.CO_UNID, V.CO_VEND, V.CO_COLE, V.CO_CLIE, V.CO_ITEM;
----COMMIT;
----EXECUTE IMMEDIATE 'ANALYZE TABLE OFIVENT.TWREPO_VENT_0003 ESTIMATE STATISTICS';
-- INSERTA EN LA TABLA TEMPORAL
INSERT /*+ APPEND */ INTO OFIVENT.TWREPO_VENT_0005
( CO_UNID, CO_VEND, CO_COLE, CO_CLIE, CO_ITEM, ID_SESS)
SELECT CO_UNID, CO_VEND, CO_COLE, CO_CLIE, CO_ITEM, ISID_SESS
FROM (
SELECT DISTINCT T1.CO_UNID, T1.CO_VEND, T1.CO_COLE, T1.CO_CLIE, T2.CO_ITEM
----- FROM TCGUIA T1,TDGUIA T2,
FROM TCGUIA T1 INNER JOIN TDGUIA T2 ON (
T2.CO_EMPR = T1.CO_EMPR
AND T2.CO_UNID = T1.CO_UNID
AND T2.NU_GUIA = T1.NU_GUIA)
INNER JOIN
(SELECT DISTINCT T31.CO_CLIE AS CO_CLIE
FROM TMCLIE T31 , TTUBIC_ALMA T32
WHERE T31.CO_EMPR = ISCO_EMPR
AND ((ISCO_CLIE IS NOT NULL AND T31.CO_CLIE = ISCO_CLIE) OR ISCO_CLIE IS NULL)
AND ((ISTI_CLIE IS NOT NULL AND T31.TI_CLIE = ISTI_CLIE) OR ISTI_CLIE IS NULL)
AND T32.CO_EMPR = T31.CO_EMPR
AND T32.CO_UBIC_ALMA = T31.CO_CLIE
AND ROWNUM>= 1) T3 ON (
T3.CO_CLIE = T1.CO_CLIE)
INNER JOIN
(SELECT CO_VEND
FROM TMVEND
WHERE CO_EMPR = ISCO_EMPR
AND ((ISCO_VEND IS NOT NULL AND CO_VEND = ISCO_VEND) OR ISCO_VEND IS NULL)
AND (( ISTI_VEND IS NOT NULL AND TI_VEND = ISTI_VEND) OR ISTI_VEND IS NULL)
AND ROWNUM>= 1) T4 ON (
T4.CO_VEND = T1.CO_VEND)
INNER JOIN TTTIPO_FACT_REPO T5 ON (
T5.CO_EMPR = T1.CO_EMPR
AND T5.TI_FACT = T1.TI_FACT)
INNER JOIN TMITEM T55 ON (
T55.CO_ITEM = T2.CO_ITEM
AND T55.CO_COR1 = T2.CO_COR1
AND T55.TI_PRES = T2.TI_PRES
AND T55.CO_COR2 = T2.CO_COR2)
LEFT JOIN TWRUBR_ERBQ T6 ON (
T55.CO_RUBR = T6.CO_RUBR)
LEFT JOIN TWITEM_ERBQ T7 ON (
T55.CO_ITEM = T7.CO_ITEM
AND T55.CO_COR1 = T7.CO_COR1
AND T55.TI_PRES = T7.TI_PRES
AND T55.CO_COR2 = T7.CO_COR2)

---- TTTIPO_FACT_REPO T5,
---- TMITEM T55,
--- TWRUBR_ERBQ T6,
----- TWITEM_ERBQ T7
WHERE T1.CO_EMPR = ISCO_EMPR
AND T1.FE_GUIA >= IDFE_INIC
AND T1.FE_GUIA <= IDFE_FINA
AND exists ( SELECT T43.CO_UNID
---FROM TTTIPO_INF1 T41, , TMUNID_VENT T43
FROM TTTIPO_INF1 T41
INNER JOIN TRINFO_GRUP T42 ON (
T42.CO_EMPR = T41.CO_EMPR
AND T42.TI_INF1 = T41.TI_INF1)
INNER JOIN TMUNID_VENT T43 ON (
T43.CO_EMPR = T42.CO_EMPR
AND T43.CO_UNID = T42.TI_INF2)
WHERE T41.CO_EMPR = ISCO_EMPR
AND T41.CO_SIST = ISCO_SIST
AND T42.CO_GRUP = ISCO_USUA
AND ((ISCO_UNID IS NOT NULL AND T43.CO_UNID = ISCO_UNID) OR ISCO_UNID IS NULL )
AND ROWNUM >= 1)
AND ((ISCO_COLE IS NOT NULL AND T1.CO_COLE = ISCO_COLE) OR ISCO_COLE IS NULL)
AND T1.ST_DOCU != 'ANU'
AND T5.ST_CONS = ISST_CONS
AND T6.ID_SESS = ISID_SESS
AND T7.ID_SESS = ISID_SESS
AND ((ISSE_SELE = 'A' AND T7.CO_ITEM = T55.CO_ITEM
AND T7.ID_SESS = ISID_SESS)
OR
(ISSE_SELE = 'R' AND T6.CO_RUBR = T55.CO_RUBR
AND T6.ID_SESS = ISID_SESS)
OR
(ISSE_SELE = 'F' AND T6.CO_RUBR = T55.CO_RUBR
AND T6.CO_FAMI = T55.CO_FAMI
AND T6.ID_SESS = ISID_SESS)
OR
(ISSE_SELE = 'S' AND T6.CO_RUBR = T55.CO_RUBR
AND T6.CO_FAMI = T55.CO_FAMI
AND T6.CO_SFAM = T55.CO_SFAM
AND T6.ID_SESS = ISID_SESS)
OR ISSE_SELE = 'N'));
------ COMMIT;
-------EXECUTE IMMEDIATE 'ANALYZE TABLE OFIVENT.TWREPO_VENT_0005 ESTIMATE STATISTICS';
INSERT /*+ APPEND */ INTO OFIVENT.TWREPO_VENT_0004
(CO_UNID, CO_VEND, CO_COLE, CO_CLIE, CO_ITEM, CA_INGR, CA_DEVS, CA_DEVO_NCRE, CA_SALI, CA_INGR_OTRO, CA_SALI_OTRO, ID_SESS)
SELECT TT.CO_UNID, CO_VEND, CO_COLE, TT.CO_CLIE, TT.CO_ITEM,
NVL(SUM( INSTR('I', T1.TI_MOVI) * INSTR('GIV', T2.TI_DOCU) * NVL(T1.CA_UBIC, 0) ),0) AS CA_INGR,
NVL(SUM( INSTR('S', T1.TI_MOVI) * INSTR('STR', T2.TI_DOCU) * NVL(T1.CA_UBIC,0) ),0) AS CA_DEVS,
NVL(SUM((INSTR('I', T1.TI_MOVI) * INSTR(VSTI_DOCU_NCRE, T2.TI_DOCU))* NVL(T1.CA_UBIC, 0)),0) AS CA_DEVO_NCRE,
NVL(SUM((INSTR('S', T1.TI_MOVI) * (INSTR(VSTI_DOCU_FACT, T2.TI_DOCU) +
INSTR(VSTI_DOCU_BOLE, T2.TI_DOCU) +
INSTR(VSTI_DOCU_TICK, T2.TI_DOCU))) * NVL(T1.CA_UBIC, 0)),0) AS CA_SALI,
NVL(SUM( INSTR('I', T1.TI_MOVI) * (1 - INSTR('GIV', T2.TI_DOCU)) * NVL(T1.CA_UBIC, 0)),0) AS CA_INGR_OTRO,
NVL(SUM( INSTR('S', T1.TI_MOVI) * (1 - INSTR(VSTI_DOCU_FACT, T2.TI_DOCU)
- INSTR(VSTI_DOCU_BOLE, T2.TI_DOCU)
- INSTR(VSTI_DOCU_TICK, T2.TI_DOCU)
- INSTR('STR', T2.TI_DOCU)) * NVL(T1.CA_UBIC, 0)),0) AS CA_SALI_OTRO,
MAX(TT.ID_SESS)
----FROM OFIVENT.TWREPO_VENT_0005 TT, TDMOVI_UBIC T1, TCDOCU_ALMA T2

FROM OFIVENT.TWREPO_VENT_0005 TT INNER JOIN TDMOVI_UBIC T1
ON (
T1.CO_UNID = TT.CO_UNID
AND T1.CO_UBIC_ALMA = TT.CO_CLIE
AND T1.CO_ITEM = TT.CO_ITEM)
INNER JOIN TCDOCU_ALMA T2 ON (
T2.CO_EMPR = T1.CO_EMPR
AND T2.CO_UNID = T1.CO_UNID
AND T2.CO_ALMA = T1.CO_ALMA
AND T2.TI_DOCU = T1.TI_DOCU
AND T2.NU_DOCU = T1.NU_DOCU )

WHERE T1.CO_EMPR = ISCO_EMPR
AND TT.ID_SESS = ISID_SESS
AND (TT.CO_VEND IS NOT NULL OR TT.CO_VEND IS NULL)
AND (TT.CO_COLE IS NOT NULL OR TT.CO_COLE IS NULL)
AND T2.FE_DOCU >= IDFE_INIC
AND T2.FE_DOCU <= IDFE_FINA
AND T2.TI_SITU != 'ANU'
GROUP BY TT.CO_UNID, CO_VEND, CO_COLE, TT.CO_CLIE, TT.CO_ITEM;
COMMIT;
-----EXECUTE IMMEDIATE 'ANALYZE TABLE OFIVENT.TWREPO_VENT_0004 ESTIMATE STATISTICS';
--233 SEGUNDOS EN TOTAL
--Se abre cursor
Open CU_SSP_TWREPO_VENT_I01_1;
Loop
Fetch CU_SSP_TWREPO_VENT_I01_1
Into CSCO_UNID, CSCO_VEND, CSCO_COLE, CSCO_CLIE, CSCO_ITEM,
VNCA_INGR_GUIA, VNMO_INGR_GUIA_DOLA, VNMO_INGR_GUIA_SOLE,
VNCA_FACT, VNMO_FACT_DOLA, VNMO_FACT_SOLE, VNCA_DEVO_NCRE,
VNMO_DEVO_NCRE_DOLA, VNMO_DEVO_NCRE_SOLE,
VNCA_INGR, VNCA_DEVS, VNCA_DEVO_NCRE2 , VNCA_SALI,
VNCA_INGR_OTRO, VNCA_SALI_OTRO;
Exit When CU_SSP_TWREPO_VENT_I01_1 %NOTFOUND;
--DBMS_APPLICATION_INFO.set_client_info(VSID);
VSCO_UNID := CSCO_UNID;
VSCO_VEND := CSCO_VEND;
VSCO_COLE := CSCO_COLE;
VSCO_CLIE := CSCO_CLIE;
VSCO_ITEM := CSCO_ITEM;
-- Obtenemos la cantidad y montos(S/. y $) de la guia
-- dependiendo de la empresa, fechas, consignacion y/o venta directa,
-- y del cursor; unidad, cliente, item y con/sin colegio
-- Obtenemos la cantidad y montos(S/. y $) de los documentos del cliente (BOL FAC TIK)
-- dependiendo de la empresa, fechas, consignacion y/o venta directa,
-- y del cursor; unidad, cliente, item y con/sin colegio
--Obtenemos datos de Colegio: codigo y nombre
Begin
Select CO_COLE, DE_NOMB
Into VSCO_COLE, VSNO_COLE
From TMCOLE
Where CO_EMPR = ISCO_EMPR
And CO_COLE = CSCO_COLE;
Exception When NO_DATA_FOUND Then
--Como no tiene colegio, seteamos en null el codigo y nombre del colegio
Begin
VSCO_COLE := NULL;
VSNO_COLE := NULL;
End;
End;
--Obtenemos datos de Cliente: codigo, tipo, descri tipo y nombre clie
Begin
Select t1.CO_CLIE, t1.TI_CLIE, t2.DE_TIPO_CLIE, t1.NO_CLIE
Into VSCO_CLIE, VSTI_CLIE, VSDE_TIPO_CLIE, VSNO_CLIE
---From TMCLIE t1, TTTIPO_CLIE t2
From TMCLIE t1 RIGHT JOIN TTTIPO_CLIE t2 ON (
t2.TI_CLIE= t1.TI_CLIE)
Where t1.CO_EMPR = ISCO_EMPR
And t1.CO_CLIE = CSCO_CLIE;

Exception When NO_DATA_FOUND Then
Begin
VSCO_CLIE := NULL;
VSTI_CLIE := NULL;
VSDE_TIPO_CLIE := NULL;
VSNO_CLIE := NULL;
End;
End;
--Obtenemos datos de Promotor: tipo, descri tipo, codigo y nombre promotor
Begin
Select t1.TI_VEND, t2.DE_TIPO_VEND,
Nvl(t1.CO_VEND, 'SIN VENDEDOR'),
t1.NO_VEND || ' ' || t1.AP_PATE_VEND || ' ' || t1.AP_MATE_VEND
Into VSTI_VEND, VSDE_TIPO_VEND, VSCO_VEND, VSNO_VEND
From TMVEND t1, TTTIPO_VEND t2
Where t1.CO_EMPR = ISCO_EMPR
And t1.CO_VEND = CSCO_VEND
And t2.TI_VEND (+)= t1.TI_VEND;
Exception When NO_DATA_FOUND Then
Begin
VSTI_VEND := NULL;
VSDE_TIPO_VEND := NULL;
VSCO_VEND := NULL;
VSNO_VEND := NULL;
End;
End;
--Obtenemos datos de Articulo: codigo, descri, descri_largo, rubro, familia y subfamilia



Begin
Select T1.CO_ITEM, T1.DE_ITEM, T1.DE_ITEM_LARG, T1.CO_MONE,
T2.CO_RUBR, T2.DE_RUBR,
T2.CO_FAMI, T2.DE_FAMI,
T2.CO_SFAM, T2.DE_SFAM
Into VSCO_ITEM, VSDE_ITEM, VSDE_ITEM_LARG, VSCO_MONE,
VSCO_RUBR, VSDE_RUBR,
VSCO_FAMI, VSDE_FAMI,
VSCO_SFAM, VSDE_SFAM
----- From TMITEM T1, TWRUBR_ERBQ T2, TWITEM_ERBQ T3
From TMITEM T1 LEFT JOIN TWRUBR_ERBQ T2 ON
(
T1.CO_RUBR = T2.CO_RUBR )
LEFT JOIN TWITEM_ERBQ T3 ON
(
T1.CO_ITEM = T3.CO_ITEM
And T1.CO_COR1 = T3.CO_COR1
And T1.TI_PRES = T3.TI_PRES
And T1.CO_COR2 = T3.CO_COR2)
Where T1.CO_EMPR = ISCO_EMPR
And T1.CO_ITEM = CSCO_ITEM
And T2.ID_SESS = ISID_SESS
And T3.ID_SESS = ISID_SESS
And ((ISSE_SELE = 'A' And T3.CO_ITEM = T1.CO_ITEM
And T3.ID_SESS = ISID_SESS)
Or
(ISSE_SELE = 'R' And T2.CO_RUBR = T1.CO_RUBR
And T2.ID_SESS = ISID_SESS)
Or
(ISSE_SELE = 'F' And T2.CO_RUBR = T1.CO_RUBR
And T2.CO_FAMI = T1.CO_FAMI
And T2.ID_SESS = ISID_SESS)
Or
(ISSE_SELE = 'S' And T2.CO_RUBR = T1.CO_RUBR
And T2.CO_FAMI = T1.CO_FAMI
And T2.CO_SFAM = T1.CO_SFAM
And T2.ID_SESS = ISID_SESS)
Or ISSE_SELE = 'N');
End;



--Recupero la suma de ingr/ Sal durante el ultimo mes cerrado
--hasta la fecha de inventario
/* I***********************************************************/
BEGIN
SELECT NVL(SUM(CASE WHEN CO_UBIC_DEST = CSCO_CLIE
THEN NVL(CA_REUB, 0)
ELSE 0
END), 0),
NVL(SUM(CASE WHEN CO_UBIC_ORIG = CSCO_CLIE
THEN NVL(CA_REUB, 0)
ELSE 0
END), 0)
INTO VNCA_INGR_REUB, VNCA_SALI_REUB
From TCREUB_ALMA
Where CO_EMPR = ISCO_EMPR
And CO_UNID = CSCO_UNID
And CO_ITEM = CSCO_ITEM
And FE_REUB >= IDFE_INIC
And FE_REUB <= IDFE_FINA;
EXCEPTION
WHEN NO_DATA_FOUND THEN
begin
VNCA_INGR_REUB := 0;
VNCA_SALI_REUB := 0;
end;
END;


--Recupero la suma de ingresos Por reubicaciones durante el
--ultimo mes cerrado hasta la fecha de Cierre
--Calcula monto en dolares y soles de devolucion cons., otros ingresos y otras salidas.
Begin
Select Round(Nvl(T2.CA_DEVS * ( T1.PR_VENT / Power( INFA_CAMB, Instr(VSCO_MONE, VSCO_MONE_NACI))),0),2) As MO_DEVS_DOLA,
Round(Nvl(T2.CA_DEVS * ( T1.PR_VENT * Power( INFA_CAMB, Instr(VSCO_MONE, VSCO_MONE_EXTR))),0),2) As MO_DEVS_SOLE,
Round(Nvl((T2.CA_INGR_OTRO + VNCA_INGR_REUB) * ( T1.PR_VENT / Power( INFA_CAMB, Instr(VSCO_MONE, VSCO_MONE_NACI))),0),2) As MO_INGR_OTRO_DOLA,
Round(Nvl((T2.CA_INGR_OTRO + VNCA_INGR_REUB) * ( T1.PR_VENT * Power( INFA_CAMB, Instr(VSCO_MONE, VSCO_MONE_EXTR))),0),2) As MO_INGR_OTRO_SOLE,
Round(Nvl((T2.CA_SALI_OTRO + VNCA_SALI_REUB) * ( T1.PR_VENT / Power( INFA_CAMB, Instr(VSCO_MONE, VSCO_MONE_NACI))),0),2) As MO_SALI_OTRO_DOLA,
Round(Nvl((T2.CA_SALI_OTRO + VNCA_SALI_REUB) * ( T1.PR_VENT * Power( INFA_CAMB, Instr(VSCO_MONE, VSCO_MONE_EXTR))),0),2) As MO_SALI_OTRO_SOLE,
Nvl((T2.CA_INGR_OTRO + VNCA_INGR_REUB),0) AS CA_INGR_OTRO,
Nvl((T2.CA_SALI_OTRO + VNCA_SALI_REUB),0) AS CA_SALI_OTRO
Into VNMO_DEVS_DOLA, VNMO_DEVS_SOLE, VNMO_INGR_OTRO_DOLA, VNMO_INGR_OTRO_SOLE, VNMO_SALI_OTRO_DOLA, VNMO_SALI_OTRO_SOLE, VNCA_INGR_OTRO, VNCA_SALI_OTRO
---- From TDITEM_UNVT T1, OFIVENT.TWREPO_VENT_0004 T2
From TDITEM_UNVT T1 INNER JOIN
OFIVENT.TWREPO_VENT_0004 T2 ON
(
T2.CO_ITEM = T1.CO_ITEM)
Where T1.CO_EMPR = ISCO_EMPR
And T1.CO_ITEM = CSCO_ITEM
AND T2.ID_SESS = ISID_SESS
AND T2.CO_UNID = CSCO_UNID
AND T2.CO_CLIE = CSCO_CLIE
AND T2.CO_VEND = CSCO_VEND
AND ((CSCO_COLE IS NOT NULL AND T2.CO_COLE = CSCO_COLE) OR (T2.CO_COLE IS NULL AND CSCO_COLE IS NULL));

EXCEPTION
WHEN NO_DATA_FOUND THEN
BEGIN
VNMO_DEVS_DOLA := 0;
VNMO_DEVS_SOLE := 0;
VNMO_INGR_OTRO_DOLA := 0;
VNMO_INGR_OTRO_SOLE := 0;
VNMO_SALI_OTRO_DOLA := 0;
VNMO_SALI_OTRO_SOLE := 0;
VNCA_INGR_OTRO := 0;
VNCA_SALI_OTRO := 0;
END;
End;
--Insertamos la informacion obtenida en la tabla temporal TWREPO_VENT
Begin
Insert Into OFIVENT.TWREPO_VENT
(ID_SESS, CO_UNID,
CO_VEND, NO_VEND, TI_VEND, DE_TIPO_VEND,
CO_COLE, NO_COLE,
CO_CLIE, NO_CLIE, TI_CLIE, DE_TIPO_CLIE,
CO_ITEM, DE_ITEM, DE_ITEM_LARG,
CO_RUBR, DE_RUBR,
CO_FAMI, DE_FAMI, CO_SFAM, DE_SFAM,
CA_INGR_GUIA, MO_INGR_GUIA_DOLA, MO_INGR_GUIA_SOLE,
CA_INGR_OTRO, MO_INGR_OTRO_DOLA, MO_INGR_OTRO_SOLE,
CA_NCRE, MO_NCRE_DOLA, MO_NCRE_SOLE,
CA_SALI_OTRO, MO_SALI_OTRO_DOLA, MO_SALI_OTRO_SOLE,
CA_FACT, MO_FACT_DOLA, MO_FACT_SOLE,
CA_DEVO_NCRE, MO_DEVO_NCRE_DOLA, MO_DEVO_NCRE_SOLE)
Values
(ISID_SESS, VSCO_UNID,
VSCO_VEND, VSNO_VEND, VSTI_VEND, VSDE_TIPO_VEND,
VSCO_COLE, VSNO_COLE,
VSCO_CLIE, VSNO_CLIE, VSTI_CLIE, VSDE_TIPO_CLIE,
VSCO_ITEM, VSDE_ITEM, VSDE_ITEM_LARG,
VSCO_RUBR, VSDE_RUBR,
VSCO_FAMI, VSDE_FAMI, VSCO_SFAM, VSDE_SFAM,
VNCA_INGR_GUIA, VNMO_INGR_GUIA_DOLA, VNMO_INGR_GUIA_SOLE,
VNCA_INGR_OTRO, VNMO_INGR_OTRO_DOLA, VNMO_INGR_OTRO_SOLE,
VNCA_DEVS, VNMO_DEVS_DOLA, VNMO_DEVS_SOLE,
VNCA_SALI_OTRO, VNMO_SALI_OTRO_DOLA, VNMO_SALI_OTRO_SOLE,
VNCA_FACT, VNMO_FACT_DOLA, VNMO_FACT_SOLE,
VNCA_DEVO_NCRE, VNMO_DEVO_NCRE_DOLA, VNMO_DEVO_NCRE_SOLE);
COMMIT;
End;
End Loop;
Close CU_SSP_TWREPO_VENT_I01_1;
End;

Martin

16/6/2012
remplazo de or por and
tengo entendido que siempre que sea posible debemos tratar de reemplazar las condiciones del where que incluyen and por or.
Ejemplo
Where (a=@a or b=@b)

forma mas eficiente
Where not (a!=@a and b!=@b)

Martin

16/6/2012
Reemplazar los OR por AND
Tengo entendido que siempre que sea posible debemos tratar de reemplazar las condiciones del where que incluyen OR por AND, pues en un OR el motor debe analizar todas las partes de la condición, sin embargo en un AND cuando encuentra una condición que no se cumple no analiza la siguiente por lo que debe procesar menos
Ejemplo
Where (a=@a or b=@b)

forma mas eficiente
Where not (a!=@a and b!=@b)

teozficio

17/5/2013
OPTIMIZAR CONSULTA
Buen dia, ojalá me pudieran ayudar con esta consulta SQL. En mi trabajo utlizamos el as/400, de este servidor debo de hacer unas consultas donde me muestre la suma total del producto terminado que se reportó en el dia, pero es muy grande la cantidad de registros, que tárda demasiado al hacer la consulta. La consulta que hago es la siguiente:

Set rs400 = cn400.Execute("SELECT SUM(BPCSFZ81.ITH.TQTY) AS TOTAL,BPCSFZ81.ITH.TWHS,BPCSFZ81.ITH.TLOCT FROM BPCSFZ81.ITH WHERE (BPCSFZ81.ITH.TTYPE='PR') AND BPCSFZ81.ITH.TTDTE = (year(curdate())*10000 + month(curdate())*100 + day(curdate())) AND BPCSFZ81.ITH.TPROD = '" & PARTE.Text & "'GROUP BY BPCSFZ81.ITH.TPROD,BPCSFZ81.ITH.TWHS,BPCSFZ81.ITH.TLOCT")

Si me pueden hechar la mano a optimizar dicha consulta, se los agradeceré mucho. Gracias.