Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 11-05-2016
jnavapal jnavapal is offline
Miembro
NULL
 
Registrado: may 2016
Posts: 10
Poder: 0
jnavapal Va por buen camino
Consulta Insert Lenta

Buenos Tardes.
En primer lugar me presento . Soy Jose Carlos un informático que esta aprendiendo a la vez que luchando con el mundo SQL y busco un poco vuestra ayuda.

Actualmente me he encotnrado una query que se demora muchisimo y estoy seguro que tiene q existir otra forma de realizarla. No obstante no consigo encontrarla.

La query en si es un Insert que en el where tiene una subquery para comprobar que no inserta dos veces lo mismo. He probado con group by y demas pero no consigo solucionar este "bucle" de insercion consulta insercion etc.

Os pongo la query .

Código SQL [-]
INSERT  INTO TABLA_A ( RPC_PER_RES, RPC_COD_EST, RPC_COD_BASE, RPC_COD_RES,
        RPC_COD_PROD, RPC_COD_POLI, RPC_COD_COBE,
        RPC_NUM_HOM, RPC_RES_HOM, RPC_EDAD_HOM,
        RPC_OBS_STAT, RPC_COD_LOB, RPC_COD_CHANNEL, RPC_COD_CLASE, RPC_COD_SUN)
        SELECT periodo,     pEstado, 'COL', 'RK',
        decode(a.riesgo_principal,'ca','c', a.riesgo_principal),
         poliza, cobertura,
        COUNT(distinct GRUPO||IDOPERACION||nvl(NUMEROASEGURADO,0)||nvl(NUMEROCARGA,0)),
        sum(nvl(cap_inicuf,0)),
        sum(trunc(months_between(last_day(to_date(periodo,'yyyymm')),fechanac)/12))/count(*),
        'VALORES A' ,
        lineanegocio, canaldeventa, ideerr, CODINTEGRACION
        from  TABLAGRANDE a, MENSUAL h
        where periodo = pPeriodo
        AND NVL (aquienafecta, 'x') <> 'P'
        AND NVL(aju_afecto,0) = 0
        AND NVL(aju_exento,0) = 0
        AND EXISTS ( SELECT NULL
                 FROM temp_polizas iwf
                 WHERE iwf.lineanegocio != 5
                 AND iwf.poliza = h.poliza
                 AND iwf.periodocobro != 'U'
                 AND RIESGO != 'DG' )
        AND NOT EXISTS  (SELECT RPC_COD_POLI
                                        FROM TABLA_A
                                        WHERE RPC_PER_RES = pPeriodo
                                        AND RPC_COD_EST = pEstado
                                        AND RPC_COD_BASE = 'COL'
                                        AND RPC_COD_RES = 'RK'
                                        AND RPC_COD_PROD = producto
                                        AND RPC_COD_POLI = to_char(poliza)
                                        AND RPC_COD_COBE = to_char(cobertura) )
        AND add_months(h.hasta, nvl(PRIMAMESESDELTA,0)) >= LAST_DAY (TO_DATE (pPeriodo, 'yyyymm'))
        AND a.RIESGO = h.RIESGO
        group by periodo,
        decode(a.riesgo_principal,'ca','c', a.riesgo_principal),
        poliza, cobertura,
        lineanegocio, canaldeventa, ideerr, CODINTEGRACION ;



Muchas gracias de antemano por la ayuda
Responder Con Cita
  #2  
Antiguo 11-05-2016
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.269
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Así, sólo con la SQL es bastante difícil saber dónde puede estar el problema.
Lo primero sería que comentaras con qué motor trabajas (esto por situarnos), luego lo suyo sería que intentarás acceder al PLAN DE EJECUCIÓN de la consulta. Si supueramos el gestor y kla herramientas que estás utilizando podríamos decirte cómo obtenerlo.

Una vez visto el plan, deberías poder saber qué parte de la consulta está tardando más de la cuenta. El SELECT, la INSERCIÓN (triggers), las ORDENACIONES, el GROUP BY, la SUBSELECT,...

Y una vez que sepas la parte que está tardando podrás intuir qué es lo que hay que optimizar.

Imagino que tienes definidas PK's, índices,...
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 11-05-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Cita:
una subquery para comprobar que no inserta dos veces lo mismo
Eso suena a "estoy usando un cuchillo para sacar un tornillo"

Hay maneras mucho mas faciles de solventar tu problema:

- Podrias definir claves primarias compuestas
- O podrias usar un trigger para validar la insercion

Por otra parte, una consulta SQL de ese tamaño a mi me resulta alarmante

Otros problemas que hacen que sea lenta es que usas mucho strings, convertis entre varios tipos de datos, y no es una subconsulta, son tres
Responder Con Cita
  #4  
Antiguo 12-05-2016
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Es que eso no es un "insert", eso es un insert con un select anidado...
y un count distinct y un sum, y otro sum, y un count(*) !!!
y otro exists con otro select anidado, y un not exists con otro select anidado...
y un group by
y todo aderezado de montones de campos de texto, concatenaciones de campos, ...

No es un insert, es un desastre

Me temo que tendrás que ir poco a poco, probando cada parte del código para ir mejorándolo y afinándolo.

Última edición por Casimiro Notevi fecha: 12-05-2016 a las 01:50:14.
Responder Con Cita
  #5  
Antiguo 12-05-2016
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Ahi lo que veo mas problematico son los EXIST y mas que todo el NOT EXIST. Normalmente eso no es muy eficiente de hacer.

Que el SELECT de insercion sea "grande" no es en si el problema (es posible hacer inserciones de 1-4GB -dependiendo de motor y parametros- en unos <200 segundos en hardware medio medio, siempre y cuando todo este alineado ). Asi que pon atencion a lo que te estan diciendo que eso se puede mejorar bastante...
__________________
El malabarista.
Responder Con Cita
  #6  
Antiguo 12-05-2016
jnavapal jnavapal is offline
Miembro
NULL
 
Registrado: may 2016
Posts: 10
Poder: 0
jnavapal Va por buen camino
Explain Plan y Aclaraciones

Os comento un poco mas. Esta query ya existía en un PL SQL y me alarmo mucho. Y estoy intento optmizarla , por no decir hacerla bien. Al hacer prueba comprobé que uno de los principales problemas era el tema de comprobar si estaba insertado ya en al tabla en la que había insertado.
Aunque llevo dándole vueltas y se q esta mal , no se me ocurre que hacer.Por eso acudo a vuestra ayuda.

Por cierto la info que me solicitabais .

BBDD Oracle 10g

Programa con el que trabajo TOAD

Explain plan
Plan
INSERT STATEMENT ALL_ROWSCost: 132.612 Bytes: 287 Cardinality: 1
9 SORT GROUP BY Cost: 132.612 Bytes: 287 Cardinality: 1
8 HASH JOIN ANTI Cost: 132.611 Bytes: 287 Cardinality: 1
6 NESTED LOOPS Cost: 6.437 Bytes: 252 Cardinality: 1
4 NESTED LOOPS Cost: 6.436 Bytes: 244 Cardinality: 1
2 SORT UNIQUE Cost: 202 Bytes: 704.256 Cardinality: 44.016
1 TABLE ACCESS FULL TABLE temp_polizas Cost: 202 Bytes: 704.256 Cardinality: 44.016
3 REMOTE REMOTE SERIAL_FROM_REMOTE MENSUAL CONSULTA.WORLDCost: 1.073 Bytes: 228 Cardinality: 1
5 REMOTE REMOTE SERIAL_FROM_REMOTE TABLAGRANDE Cost: 1 Bytes: 8 Cardinality: 1
7 TABLE ACCESS FULL TABLE TABLA_A Cost: 126.173 Bytes: 996.030 Cardinality: 28.458

Por cierto muchísimas gracias por la ayuda que dais.

Un saludo
Responder Con Cita
  #7  
Antiguo 12-05-2016
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por jnavapal Ver Mensaje
...uno de los principales problemas era el tema de comprobar si estaba insertado ya en al tabla en la que había insertado.
Solo es necesario crear una clave o índice único por ese campo, y automáticamente saltará una excepción indicando que ya existe.
Responder Con Cita
  #8  
Antiguo 12-05-2016
jnavapal jnavapal is offline
Miembro
NULL
 
Registrado: may 2016
Posts: 10
Poder: 0
jnavapal Va por buen camino
Clave

El problema es que en esa tabla se hacen otras inserciones que si pueden repetirse . Solo son las que vienen las de este insert las que no.
Responder Con Cita
  #9  
Antiguo 12-05-2016
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por jnavapal Ver Mensaje
El problema es que en esa tabla se hacen otras inserciones que si pueden repetirse . Solo son las que vienen las de este insert las que no.
¿Pero no estás hablando de un campo que no se puede repetir?
Responder Con Cita
  #10  
Antiguo 12-05-2016
jnavapal jnavapal is offline
Miembro
NULL
 
Registrado: may 2016
Posts: 10
Poder: 0
jnavapal Va por buen camino
Clave

No se puede repetir los que provienen de ese insert (para ser mas exacto de ese select) . Seguidamente tiene otros insert que se basan en select distintos y si podrían repetirse.

es decir al solucion de una clave , la contemple pero me encontré con ese problema. Lo que pensé como "solución intermedia" es una tabla temporal con la clave y después un insert con un select de la tabla temporal. La cosa es que me niego a pensar que sea la mejora solución....
Responder Con Cita
  #11  
Antiguo 12-05-2016
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Sigo sin entender. ¿Es un campo que no puede repetir datos si los inserta "un usuario", pero sí puede repetir datos si los inserta "otro usuario"?
Un campo admite/no admite repetir información, pero no vale eso de a veces sí y a veces no.
¿Cómo sabes que cuando se insertó estaba permitido que se repetiera o no?
Está mal ideada la estructura... eso no puede funcionar así.
Responder Con Cita
  #12  
Antiguo 12-05-2016
jnavapal jnavapal is offline
Miembro
NULL
 
Registrado: may 2016
Posts: 10
Poder: 0
jnavapal Va por buen camino
Clave

Buenas Casimiro siento sino me he explicado bien.

Actualmente tengo una tabla TablaA esta tabla se rellena por varios insert (5 en total)

Estos insert hacen select a tablas distintas:

Insert INTO TABLA_A Select TablaB
Insert INTO TABLA_A Select TablaGrande
Insert INTO TABLA_A Select TablaC
Insert INTO TABLA_A Select TablaD
Insert INTO TABLA_A Select TablaE

Al insertarlos solo me interesa que no se repitan los de la TablaGrande. Es decir pueden existir en TABLA_A dos personas iguales , siempre y cuando no provengan de las TABLA_GRANDE.
Por este motivo no puedo poner clave, ya que de la tabla C y tabla D si pueden existir registros duplicados.

Esta premisa es la que me rompe la cabeza. Ya que sino con las claves como bien dijiste se solucionaría el problema.

Un saludo y de nuevo gracias por la ayuda y perdón por no explicarme bien desde el principio.
Responder Con Cita
  #13  
Antiguo 12-05-2016
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Sigo sin entender, o tienes mal los conceptos. A ver si con un sencillo ejemplo nos entendemos.
Una tabla tiene campos, ejemplo:
Código SQL [-]
create tbTablaA (
  id integer not null,
  nombre varchar(64),
  sueldo double
);
No quieres que se repita el campo nombre ¿es eso?
Tienes varias opciones, pero NO VALE permitir nombres repetidos si lo hace "alguien" y no permitir nombres repetidos si lo hace "otro alguien" (Sea "alguien" lo que sea)
Eso es básico. Esa lógica no puede variarse, salvo que quieras encontrarte con graves problemas.
Y en tu caso necesitarás un campo para saber quién hace el insert y realizar unos controles u otros, dependiendo del caso.
Responder Con Cita
  #14  
Antiguo 12-05-2016
jnavapal jnavapal is offline
Miembro
NULL
 
Registrado: may 2016
Posts: 10
Poder: 0
jnavapal Va por buen camino
Veo que seguimos sin entendernos. jejejeje

No es un problema de conceptos. En la tabla_A en ningún momento he dicho que no se puedan repetir. Lo único que quiero es que no se repitan si viene de la TABLA_GRANDE.

Un ejemplo

Si tengo 5 controles de puertas y quiero tener un registro de quien ha entrado por cada puerta (A,B,C yD) y cuantas veces.

Pero hay una puerta (TABLA_X) que es de paso y pasan demasiadas veces y solo me interesa saber si alguien ha pasado y no cuantas veces.


Es decir en la tabla final , tendría
Tabla A
Juan Nuñez
Juan Nuñez

Tabla B
Juan Nuñez
Juan Nuñez
Juan Nuñez

Tabla X
Juan Nuñez
Juan Nuñez
Juan Nuñez
Pedro Perez
Pedro Perez
Pedro Perez
Pedro Perez
Pedro Perez


Tabla C
Juan Nuñez
Juan Nuñez
Pedro Perez
Pedro Perez
Pedro Perez


Tabla X
Juan Nuñez- puerta A
Juan Nuñez- puerta A
Juan Nuñez- puerta B
Juan Nuñez- puerta B
Juan Nuñez- puerta B
Juan Nuñez- puerta C
Juan Nuñez- puerta C
Pedro Perez- puerta X
Pedro Perez- puerta C
Pedro Perez- puerta C
Pedro Perez- puerta C

Juan Nuñez como paso por otras antes no la ingreso, pero si me interesa saber todos sus registros.
Pedro Perez no paso antes por ninguna y si varias veces por X . Ingreso solo 1 vez en la X y las veces de la otra.

Es un ejemplo que se me acaba de ocurrir cercano a lo que busco. Espero que ahora este mas claro.

Un saludo y muchas gracias
Responder Con Cita
  #15  
Antiguo 12-05-2016
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por jnavapal
... que no se repitan si viene de la TABLA_GRANDE.
¿Cómo sabes que viene de la tabla_grande?
Responder Con Cita
  #16  
Antiguo 12-05-2016
jnavapal jnavapal is offline
Miembro
NULL
 
Registrado: may 2016
Posts: 10
Poder: 0
jnavapal Va por buen camino
Porque son insert distintos. Que recogen los datos de tablas distintas.
Responder Con Cita
  #17  
Antiguo 12-05-2016
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Ya, pero eso lo sabes tú
El insert, la tabla, la base de datos, la sql, .... ¿cómo saben que viene de "tabla_grande" y no debe permitir repetidos y de los otros debe?
Responder Con Cita
  #18  
Antiguo 12-05-2016
jnavapal jnavapal is offline
Miembro
NULL
 
Registrado: may 2016
Posts: 10
Poder: 0
jnavapal Va por buen camino
Porque solo en el insert que pongo al principio del hilo es en el que hago la comprobación. El resto de insert se limitan a insertar los datos recogidos
Responder Con Cita
  #19  
Antiguo 12-05-2016
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Veamos, un día estás revisando datos y te encuentras con:
Cita:
1. Manuel
2. Miguel
3. Pedro
1. Manuel
4. Alberto
Ves que hay repetido el registro "Manuel", ¿cómo sabes que se insertó con esa insert o si es un error y no debería de estar repetido?
Responder Con Cita
  #20  
Antiguo 12-05-2016
jnavapal jnavapal is offline
Miembro
NULL
 
Registrado: may 2016
Posts: 10
Poder: 0
jnavapal Va por buen camino
Porque hay otra columna que t dice de donde viene. En el ejemplo ponía puerta a. Por ejemplo.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Consulta lenta DamianG Firebird e Interbase 6 20-11-2012 14:06:16
Consulta sql lenta la primera vez lledesma Conexión con bases de datos 2 07-07-2008 11:58:36
Ayuda con consulta lenta, lenta, lenta Gregory Mazon Firebird e Interbase 22 27-06-2007 09:56:38
Consulta muy lenta Walterdf Conexión con bases de datos 2 25-08-2004 18:37:57
lenta la consulta. digital Conexión con bases de datos 2 10-09-2003 15:38:13


La franja horaria es GMT +2. Ahora son las 00:14:13.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi