Consultas con muchos JOINS

17/05/2006 - 18:01 por fgabriel.munoz | Informe spam
Hola,

Tengo una consulta realmente monstruosa, que tiene 70 joins y recupera
100 columnas.
El rendimiento de esa consulta, con una media de 20.000 registros por
tabla es realmente patético.

No puedo plantearme una modificación grande en el modelo de datos (que
sin duda alguna sería la mejor opción), por lo que tengo que intentar
buscar otro tipo de "parches" para mejorar el rendimiento de la
consulta.

Es una consulta que tarda de 15 a 20 minutos en ejecutarse. ¿Qué
opciones podrían darme una mejora de rendimiento significativa? Ya
tengo indexadas todas las claves primarias y foráneas (como es
evidente). ¿Usar vistas puede ofrecerme alguna mejoría? He hecho
alguna prueba con vistas y no aprecio mejora alguna en rendimiento.

Gracias.

Preguntas similare

Leer las respuestas

#1 Alejandro Mesa
17/05/2006 - 18:59 | Informe spam
,

Puedes postear la consulta?


AMB

"" wrote:

Hola,

Tengo una consulta realmente monstruosa, que tiene 70 joins y recupera
100 columnas.
El rendimiento de esa consulta, con una media de 20.000 registros por
tabla es realmente patético.

No puedo plantearme una modificación grande en el modelo de datos (que
sin duda alguna sería la mejor opción), por lo que tengo que intentar
buscar otro tipo de "parches" para mejorar el rendimiento de la
consulta.

Es una consulta que tarda de 15 a 20 minutos en ejecutarse. ¿Qué
opciones podrían darme una mejora de rendimiento significativa? Ya
tengo indexadas todas las claves primarias y foráneas (como es
evidente). ¿Usar vistas puede ofrecerme alguna mejoría? He hecho
alguna prueba con vistas y no aprecio mejora alguna en rendimiento.

Gracias.


Respuesta Responder a este mensaje
#2 fgabriel.munoz
17/05/2006 - 19:09 | Informe spam
No asustaros:

SELECT BDC.BDC_COD AS COD, BDC.BDC_NOM AS DES, 'B' AS TIPO, BDC.BDC_FPM
AS FPM,BDC.BDC_IMP AS CAD,
BDC.BDC_EXP AS EXP, BDC.BDC_LOT AS LOT, BDC.BDC_REC AS REC, BDC.BDC_SIT
AS SIT,BDC.BDC_FAL AS FAL, BDC.BDC_TOP AS BTOP,
BTOP.TOP_CAL, BTOP.TOP_NOM,BDC.BDC_CGE, CGE_NOM, BDC.BDC_CCO, CCO_NOM,
BDC.BDC_PRP, PRP_CAL, PRP_DES, BDC.BDC_UBI, UBI_CAL,
UBI_DES, BDC.BDC_PLT, PLT_CAL, PLT_DES, BDC.BDC_ESP, ESP_CAL, ESP_DES,
BDC.BDC_SPT, SPT_NOM, BDC.BDC_NAT, NAT_NOM, BDC.BDC_USO,
USO_NOM, BDC.BDC_TLR, TLR.TER_DOC AS TLR_DOC, TLR.TER_NOM AS
TLR_NOM,BDC.BDC_GEO, BDC.BDC_BAS, BDC.BDC_BIN, BDC.BDC_BSG,
BDC.BDC_PPR,
BDC.BDC_LIB, LIB_CAL, LIB_DES, BDC.BDC_EPI AS BDC_EPI, EPI.EPI_CAL AS
EPI_CAL, EPI.EPI_NOM AS EPI_NOM,BDC.BDC_SEP AS BDC_SEP,
SEP.EPI_CAL AS SEP_CAL, SEP.EPI_NOM AS SEP_NOM,BDC.BDC_EST AS BDC_EST,
EST_NOM, BDC.BDC_FRE, BDC.BDC_IMP, BDC.BDC_PVD,
PVD.TER_DOC AS PVD_DOC, PVD.TER_NOM AS PVD_NOM, BDC.BDC_FUM,BDC.BDC_CLA
AS CLA_COD, CLA_CAL, CLA_NOM, CLA_TGE, CON_FIC,
CON_FFC, VEH_MAR, VEH_MOD, VEH_BAS, BHA_AUT,
BHA_TEM, BHA_ESC, BHA_EPC,URB_PRV, PRV_NOM, URB_MUN, MUN_NOM, URB_PLT,
URB_FAP, URB_CSU, CSU_NOM, URB_OCM, URB_CLS, URB_EDN, URB_CLF,
URB_ALM, URB_RLA, URB_NPT, URB_CAP, CAP_NOM, URB_CUL,BMU_FIG, BMU_FFG,
BMU_NSR, BMU_ETQ, CDP_FVT, AYD_FEC, RVE_FRE, DRG_FNC, DRG_REG,
REG_NOM, BDC.BDC_COD AS INV_BDC, SMV_CAB, BMU_CAN, VMB_TIT, NULL AS
INV_CAN, CTR_REF, BDC.BDC_ORF, BDC.BDC_VME, BDC.BDC_FVM, CTR_ACT,
CTR_VAL
FROM ((((((((((((((((((((((((((((((((((((((((((((((((((((((
G_BDC BDC INNER JOIN G_TOP BTOP ON BDC.BDC_TOP=BTOP.TOP_COD)
INNER JOIN G_CLA ON BDC.BDC_CLA=G_CLA.CLA_COD)
INNER JOIN G_UCL ON G_CLA.CLA_COD=G_UCL.UCL_CLA)
LEFT OUTER JOIN G_LOP ON BDC.BDC_COD=G_LOP.LOP_BDC)
LEFT OUTER JOIN G_OPE LOPE ON G_LOP.LOP_OPE=LOPE.OPE_COD)
LEFT OUTER JOIN G_BAJ ON LOPE.OPE_COD=G_BAJ.BAJ_OPE)
LEFT OUTER JOIN G_TER PVD ON BDC.BDC_PVD=PVD.TER_COD)
LEFT OUTER JOIN G_TER TLR ON BDC.BDC_TLR=TLR.TER_COD)
LEFT OUTER JOIN G_OPE UOPE ON BDC.BDC_UOP=UOPE.OPE_COD)
LEFT OUTER JOIN G_LOP UOLOP ON UOPE.OPE_COD=UOLOP.LOP_OPE)
LEFT OUTER JOIN G_VMB ON BDC.BDC_COD=G_VMB.VMB_BDC)
LEFT OUTER JOIN G_SMV ON BDC.BDC_COD=G_SMV.SMV_BDC)
LEFT OUTER JOIN G_BMU ON BDC.BDC_COD=G_BMU.BMU_BDC)
LEFT OUTER JOIN G_CDP ON BDC.BDC_COD=G_CDP.CDP_BDC)
LEFT OUTER JOIN G_CON ON BDC.BDC_COD=G_CON.CON_BDC)
LEFT OUTER JOIN G_CTR ON BDC.BDC_COD=G_CTR.CTR_BDC)
LEFT OUTER JOIN G_DRG ON BDC.BDC_COD=G_DRG.DRG_BDC)
LEFT OUTER JOIN G_DAB ON BDC.BDC_COD=G_DAB.DAB_BDC)
LEFT OUTER JOIN G_INM ON BDC.BDC_COD=G_INM.INM_BDC)
LEFT OUTER JOIN G_URB ON BDC.BDC_COD=G_URB.URB_BDC)
LEFT OUTER JOIN G_REG ON G_DRG.DRG_REG=G_REG.REG_COD)
LEFT OUTER JOIN G_BHA ON BDC.BDC_COD=G_BHA.BHA_BDC)
LEFT OUTER JOIN G_OCT ON G_CTR.CTR_OCT=G_OCT.OCT_COD)
LEFT OUTER JOIN G_VEH ON BDC.BDC_COD=G_VEH.VEH_BDC)
LEFT OUTER JOIN G_TOP LOPETOP ON LOPE.OPE_TOD=LOPETOP.TOP_COD)
LEFT OUTER JOIN G_ESP ON BDC.BDC_ESP=G_ESP.ESP_COD)
LEFT OUTER JOIN G_PLT ON BDC.BDC_PLT=G_PLT.PLT_COD)
LEFT OUTER JOIN G_UBI ON BDC.BDC_UBI=G_UBI.UBI_COD)
LEFT OUTER JOIN G_PRP ON BDC.BDC_PRP=G_PRP.PRP_COD)
LEFT OUTER JOIN G_PYB PYB ON BDC.BDC_COD=PYB.PYB_BDC)
LEFT OUTER JOIN G_PSE ON PYB.PYB_PSE=G_PSE.PSE_COD)
LEFT OUTER JOIN G_CSG ON G_PSE.PSE_CSG=G_CSG.CSG_COD)
LEFT OUTER JOIN G_TOP UOTOP ON UOPE.OPE_TOD=UOTOP.TOP_COD)
LEFT OUTER JOIN G_CTP ON UOTOP.TOP_COD=G_CTP.CTP_UOP)
LEFT OUTER JOIN G_TOP OPCTOP ON G_CTP.CTP_OPC=OPCTOP.TOP_COD)
LEFT OUTER JOIN G_CCO ON BDC.BDC_CCO=G_CCO.CCO_COD)
LEFT OUTER JOIN G_CGE ON BDC.BDC_CGE=G_CGE.CGE_COD)
LEFT OUTER JOIN G_PRV ON G_URB.URB_PRV=G_PRV.PRV_COD)
LEFT OUTER JOIN G_MUN ON G_URB.URB_PRV=G_MUN.MUN_PRV AND
G_URB.URB_MUN=G_MUN.MUN_COD)
LEFT OUTER JOIN G_UCG ON G_CGE.CGE_COD=G_UCG.UCG_CGE)
LEFT OUTER JOIN G_RVE ON LOPE.OPE_COD=G_RVE.RVE_OPE)
LEFT OUTER JOIN G_EST ON BDC.BDC_EST=G_EST.EST_COD)
LEFT OUTER JOIN G_EPI EPI ON BDC.BDC_EPI=EPI.EPI_COD)
LEFT OUTER JOIN G_EPI SEP ON BDC.BDC_SEP=SEP.EPI_COD)
LEFT OUTER JOIN G_EPI EPI2 ON BDC.BDC_EPI2=EPI2.EPI_COD)
LEFT OUTER JOIN G_LIB ON BDC.BDC_LIB=G_LIB.LIB_COD)
LEFT OUTER JOIN G_NAT ON BDC.BDC_NAT=G_NAT.NAT_COD)
LEFT OUTER JOIN G_SPT ON BDC.BDC_SPT=G_SPT.SPT_COD)
LEFT OUTER JOIN G_USO ON BDC.BDC_USO=G_USO.USO_COD)
LEFT OUTER JOIN G_AYD ON BDC.BDC_COD=G_AYD.AYD_BDC)
LEFT OUTER JOIN G_TIT ON G_DAB.DAB_TIT=G_TIT.TIT_COD)
LEFT OUTER JOIN G_CAP ON G_URB.URB_CAP=G_CAP.CAP_COD)
LEFT OUTER JOIN G_CSU ON G_URB.URB_CSU=G_CSU.CSU_COD)
LEFT OUTER JOIN G_NTR ON G_TIT.TIT_NTR=G_NTR.NTR_COD)
Respuesta Responder a este mensaje
#3 fgabriel.munoz
17/05/2006 - 19:15 | Informe spam
Hola,

El Index Wizard se me queda colgado. Lo he dejado una noche entera
intentando analizar la consulta y no me ha dado respuesta.

Con otras consultas más "simples" sí me ha funcionado, por lo que
deduzco que no es un problema de instalación del SQL Server, sino de
que la complejidad de la consulta hace realmente complicado el trabajo
de dicho asistente.
Respuesta Responder a este mensaje
#4 Alejandro Mesa
17/05/2006 - 19:24 | Informe spam
No creo que podamos hacer mucho, pues la mayoria de los operadores de tabla
son "left outer join" y ademas la sentencia no usa la clausula "where" para
filtrar el resultado.


AMB

"" wrote:

No asustaros:

SELECT BDC.BDC_COD AS COD, BDC.BDC_NOM AS DES, 'B' AS TIPO, BDC.BDC_FPM
AS FPM,BDC.BDC_IMP AS CAD,
BDC.BDC_EXP AS EXP, BDC.BDC_LOT AS LOT, BDC.BDC_REC AS REC, BDC.BDC_SIT
AS SIT,BDC.BDC_FAL AS FAL, BDC.BDC_TOP AS BTOP,
BTOP.TOP_CAL, BTOP.TOP_NOM,BDC.BDC_CGE, CGE_NOM, BDC.BDC_CCO, CCO_NOM,
BDC.BDC_PRP, PRP_CAL, PRP_DES, BDC.BDC_UBI, UBI_CAL,
UBI_DES, BDC.BDC_PLT, PLT_CAL, PLT_DES, BDC.BDC_ESP, ESP_CAL, ESP_DES,
BDC.BDC_SPT, SPT_NOM, BDC.BDC_NAT, NAT_NOM, BDC.BDC_USO,
USO_NOM, BDC.BDC_TLR, TLR.TER_DOC AS TLR_DOC, TLR.TER_NOM AS
TLR_NOM,BDC.BDC_GEO, BDC.BDC_BAS, BDC.BDC_BIN, BDC.BDC_BSG,
BDC.BDC_PPR,
BDC.BDC_LIB, LIB_CAL, LIB_DES, BDC.BDC_EPI AS BDC_EPI, EPI.EPI_CAL AS
EPI_CAL, EPI.EPI_NOM AS EPI_NOM,BDC.BDC_SEP AS BDC_SEP,
SEP.EPI_CAL AS SEP_CAL, SEP.EPI_NOM AS SEP_NOM,BDC.BDC_EST AS BDC_EST,
EST_NOM, BDC.BDC_FRE, BDC.BDC_IMP, BDC.BDC_PVD,
PVD.TER_DOC AS PVD_DOC, PVD.TER_NOM AS PVD_NOM, BDC.BDC_FUM,BDC.BDC_CLA
AS CLA_COD, CLA_CAL, CLA_NOM, CLA_TGE, CON_FIC,
CON_FFC, VEH_MAR, VEH_MOD, VEH_BAS, BHA_AUT,
BHA_TEM, BHA_ESC, BHA_EPC,URB_PRV, PRV_NOM, URB_MUN, MUN_NOM, URB_PLT,
URB_FAP, URB_CSU, CSU_NOM, URB_OCM, URB_CLS, URB_EDN, URB_CLF,
URB_ALM, URB_RLA, URB_NPT, URB_CAP, CAP_NOM, URB_CUL,BMU_FIG, BMU_FFG,
BMU_NSR, BMU_ETQ, CDP_FVT, AYD_FEC, RVE_FRE, DRG_FNC, DRG_REG,
REG_NOM, BDC.BDC_COD AS INV_BDC, SMV_CAB, BMU_CAN, VMB_TIT, NULL AS
INV_CAN, CTR_REF, BDC.BDC_ORF, BDC.BDC_VME, BDC.BDC_FVM, CTR_ACT,
CTR_VAL
FROM ((((((((((((((((((((((((((((((((((((((((((((((((((((((
G_BDC BDC INNER JOIN G_TOP BTOP ON BDC.BDC_TOP=BTOP.TOP_COD)
INNER JOIN G_CLA ON BDC.BDC_CLA=G_CLA.CLA_COD)
INNER JOIN G_UCL ON G_CLA.CLA_COD=G_UCL.UCL_CLA)
LEFT OUTER JOIN G_LOP ON BDC.BDC_COD=G_LOP.LOP_BDC)
LEFT OUTER JOIN G_OPE LOPE ON G_LOP.LOP_OPE=LOPE.OPE_COD)
LEFT OUTER JOIN G_BAJ ON LOPE.OPE_COD=G_BAJ.BAJ_OPE)
LEFT OUTER JOIN G_TER PVD ON BDC.BDC_PVD=PVD.TER_COD)
LEFT OUTER JOIN G_TER TLR ON BDC.BDC_TLR=TLR.TER_COD)
LEFT OUTER JOIN G_OPE UOPE ON BDC.BDC_UOP=UOPE.OPE_COD)
LEFT OUTER JOIN G_LOP UOLOP ON UOPE.OPE_COD=UOLOP.LOP_OPE)
LEFT OUTER JOIN G_VMB ON BDC.BDC_COD=G_VMB.VMB_BDC)
LEFT OUTER JOIN G_SMV ON BDC.BDC_COD=G_SMV.SMV_BDC)
LEFT OUTER JOIN G_BMU ON BDC.BDC_COD=G_BMU.BMU_BDC)
LEFT OUTER JOIN G_CDP ON BDC.BDC_COD=G_CDP.CDP_BDC)
LEFT OUTER JOIN G_CON ON BDC.BDC_COD=G_CON.CON_BDC)
LEFT OUTER JOIN G_CTR ON BDC.BDC_COD=G_CTR.CTR_BDC)
LEFT OUTER JOIN G_DRG ON BDC.BDC_COD=G_DRG.DRG_BDC)
LEFT OUTER JOIN G_DAB ON BDC.BDC_COD=G_DAB.DAB_BDC)
LEFT OUTER JOIN G_INM ON BDC.BDC_COD=G_INM.INM_BDC)
LEFT OUTER JOIN G_URB ON BDC.BDC_COD=G_URB.URB_BDC)
LEFT OUTER JOIN G_REG ON G_DRG.DRG_REG=G_REG.REG_COD)
LEFT OUTER JOIN G_BHA ON BDC.BDC_COD=G_BHA.BHA_BDC)
LEFT OUTER JOIN G_OCT ON G_CTR.CTR_OCT=G_OCT.OCT_COD)
LEFT OUTER JOIN G_VEH ON BDC.BDC_COD=G_VEH.VEH_BDC)
LEFT OUTER JOIN G_TOP LOPETOP ON LOPE.OPE_TOD=LOPETOP.TOP_COD)
LEFT OUTER JOIN G_ESP ON BDC.BDC_ESP=G_ESP.ESP_COD)
LEFT OUTER JOIN G_PLT ON BDC.BDC_PLT=G_PLT.PLT_COD)
LEFT OUTER JOIN G_UBI ON BDC.BDC_UBI=G_UBI.UBI_COD)
LEFT OUTER JOIN G_PRP ON BDC.BDC_PRP=G_PRP.PRP_COD)
LEFT OUTER JOIN G_PYB PYB ON BDC.BDC_COD=PYB.PYB_BDC)
LEFT OUTER JOIN G_PSE ON PYB.PYB_PSE=G_PSE.PSE_COD)
LEFT OUTER JOIN G_CSG ON G_PSE.PSE_CSG=G_CSG.CSG_COD)
LEFT OUTER JOIN G_TOP UOTOP ON UOPE.OPE_TOD=UOTOP.TOP_COD)
LEFT OUTER JOIN G_CTP ON UOTOP.TOP_COD=G_CTP.CTP_UOP)
LEFT OUTER JOIN G_TOP OPCTOP ON G_CTP.CTP_OPC=OPCTOP.TOP_COD)
LEFT OUTER JOIN G_CCO ON BDC.BDC_CCO=G_CCO.CCO_COD)
LEFT OUTER JOIN G_CGE ON BDC.BDC_CGE=G_CGE.CGE_COD)
LEFT OUTER JOIN G_PRV ON G_URB.URB_PRV=G_PRV.PRV_COD)
LEFT OUTER JOIN G_MUN ON G_URB.URB_PRV=G_MUN.MUN_PRV AND
G_URB.URB_MUN=G_MUN.MUN_COD)
LEFT OUTER JOIN G_UCG ON G_CGE.CGE_COD=G_UCG.UCG_CGE)
LEFT OUTER JOIN G_RVE ON LOPE.OPE_COD=G_RVE.RVE_OPE)
LEFT OUTER JOIN G_EST ON BDC.BDC_EST=G_EST.EST_COD)
LEFT OUTER JOIN G_EPI EPI ON BDC.BDC_EPI=EPI.EPI_COD)
LEFT OUTER JOIN G_EPI SEP ON BDC.BDC_SEP=SEP.EPI_COD)
LEFT OUTER JOIN G_EPI EPI2 ON BDC.BDC_EPI2=EPI2.EPI_COD)
LEFT OUTER JOIN G_LIB ON BDC.BDC_LIB=G_LIB.LIB_COD)
LEFT OUTER JOIN G_NAT ON BDC.BDC_NAT=G_NAT.NAT_COD)
LEFT OUTER JOIN G_SPT ON BDC.BDC_SPT=G_SPT.SPT_COD)
LEFT OUTER JOIN G_USO ON BDC.BDC_USO=G_USO.USO_COD)
LEFT OUTER JOIN G_AYD ON BDC.BDC_COD=G_AYD.AYD_BDC)
LEFT OUTER JOIN G_TIT ON G_DAB.DAB_TIT=G_TIT.TIT_COD)
LEFT OUTER JOIN G_CAP ON G_URB.URB_CAP=G_CAP.CAP_COD)
LEFT OUTER JOIN G_CSU ON G_URB.URB_CSU=G_CSU.CSU_COD)
LEFT OUTER JOIN G_NTR ON G_TIT.TIT_NTR=G_NTR.NTR_COD)


Respuesta Responder a este mensaje
#5 Jorge Gonzalez
17/05/2006 - 19:30 | Informe spam
Gabriel,

podrías utilizar el index wizard que viene con SQL SERVER para identificar
una estrategia de indices adecuada. Sin embargo no creo mejore grandemente
tu desempeño debido al diseño de tu consulta.
Si cada tabla tiene una media de 20,000 registros es probable que con un
Stored Procedure o Función puedas lograr programar un procedimiento
estructurado que cree una tabla final y vaya insertantando de acuerdoa un
algoritmo registros en dicha tabla para lograr el resultado final buscado.
Es posible que este procedimiento fuera más rápido que tu consulta actual,
pero eso no lo podemos saber sin ver la estructura y la consulta.

Una pregunta. Usas la consulta para un reporte de usuario final? un proceso
de algún tipo? porque si es para un reporte podrías crear un cubo que sea
reconstruido cada vez que el usuario requiera de la información más actual.
Esto le va a dar la sensación al usuario de que su información sale rápido
aunque vos sepás que tenés que correr el proceso de actualización del cubo
cada vez.

saludos

escribió en el mensaje
news:
Hola,

Tengo una consulta realmente monstruosa, que tiene 70 joins y recupera
100 columnas.
El rendimiento de esa consulta, con una media de 20.000 registros por
tabla es realmente patético.

No puedo plantearme una modificación grande en el modelo de datos (que
sin duda alguna sería la mejor opción), por lo que tengo que intentar
buscar otro tipo de "parches" para mejorar el rendimiento de la
consulta.

Es una consulta que tarda de 15 a 20 minutos en ejecutarse. ¿Qué
opciones podrían darme una mejora de rendimiento significativa? Ya
tengo indexadas todas las claves primarias y foráneas (como es
evidente). ¿Usar vistas puede ofrecerme alguna mejoría? He hecho
alguna prueba con vistas y no aprecio mejora alguna en rendimiento.

Gracias.
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida