Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » SQL Server »

Optimizar Consulta SQL

Estas en el tema de Optimizar Consulta SQL en el foro de SQL Server en Foros del Web. Tengo una consulta que se medio lenta ya que alrededor de 18 millones de registros .. SELECT P.COD_PERSONA,P.APE_PATERNO, P.APE_MATERNO, P.NOMBRES, P.SEXO , CASE WHEN MONTH(FEC_NACIMIENTO) ...
  #1 (permalink)  
Antiguo 17/05/2010, 13:14
 
Fecha de Ingreso: mayo-2010
Mensajes: 5
Antigüedad: 14 años
Puntos: 0
Exclamación Optimizar Consulta SQL

Tengo una consulta que se medio lenta ya que alrededor de 18 millones de registros ..

SELECT P.COD_PERSONA,P.APE_PATERNO, P.APE_MATERNO, P.NOMBRES, P.SEXO ,
CASE WHEN MONTH(FEC_NACIMIENTO) > MONTH(GETDATE()) THEN (YEAR(GETDATE()) - YEAR(FEC_NACIMIENTO) - 1)
WHEN MONTH(GETDATE()) = MONTH(FEC_NACIMIENTO) AND DAY(FEC_NACIMIENTO) > DAY(GETDATE()) THEN YEAR(GETDATE()) - YEAR(FEC_NACIMIENTO) - 1
ELSE YEAR(GETDATE()) - YEAR(FEC_NACIMIENTO) END AS EDAD,
(SELECT (SELECT REGION FROM UBIGEO WHERE COD_UBIGEO=D.UBIGEO_NAC) FROM DNI_PERSONA D WHERE D.COD_PERSONA=P.COD_PERSONA) AS LUGAR_NAC,
(SELECT NRO_DOCUMENTO FROM DNI_PERSONA D WHERE D.COD_PERSONA=P.COD_PERSONA) AS DNI,
(SELECT NRO_RUC FROM RUC_PERSONA R WHERE R.COD_PERSONA=P.COD_PERSONA) AS RUC,
(SELECT AUTOGENERADO FROM ESSALUD_PERSONA E WHERE E.COD_PERSONA=P.COD_PERSONA) AS ESSALUD
FROM TB_PERSONA P WHERE DAY(P.FEC_NACIMIENTO)='12' and month(P.FEC_NACIMIENTO)='02'

en este caso me piden la consulta por fecha de cumpleaños
y otro muy parecido (solo cambiando la condicional WHERE) con rango de edades
y no lo puedo hacer ya que este campo es calculado y esta con un alias

me podrían dar alguna solución o recomendación ante este problema

gracias.

Última edición por guntronics; 18/05/2010 a las 08:40
  #2 (permalink)  
Antiguo 17/05/2010, 16:00
Avatar de Porlachucha  
Fecha de Ingreso: noviembre-2008
Ubicación: Santiago
Mensajes: 172
Antigüedad: 15 años, 6 meses
Puntos: 5
Respuesta: Optimizar Consulta SQL

No soy muy experto, pero creo que podrias mejorar bastante en 2 puntos:

1. para calcular la edad, mejor utiliza DateDiff, en vez del codigo de calculo de meses y años que utiliza tu SP
ejemplo

select DateDiff(year, FechaNacimiento, FechaActual)

2.- puedes usar inner join en vez de select para obtener la informacion de las demas tablas. el inner hace lo mismo que tus select anidados, pero es mas eficiente, ademas, al hacer el ON, ya estas haciendo un where implicito que no necesitas filtrar despues. esto te ahorra una buena cantidad de registros que despues de todas formas eliminas

de esta forma

Código:
SELECT	P.COD_PERSONA,
		P.APE_PATERNO, 
		P.APE_MATERNO, 
		P.NOMBRES, 
		P.SEXO ,
		datediff(year, FEC_NACIMIENTO, TimeStamp) as edad,
		UB.REGION  AS LUGAR_NAC,
		D.NRO_DOCUMENTO AS DNI,
		R.NRO_RUC AS RUC,
		E.AUTOGENERADO as ESSALUD,
		
FROM TB_PERSONA P
	inner join UBIGEO UB on D.COD_PERSONA=P.COD_PERSONA
							UB.COD_UBIGEO = D.UBIGEO_NAC
	inner join DNI_PERSONA D on D.COD_PERSONA=P.COD_PERSONA
	inner join RUC_PERSONA R R.COD_PERSONA=P.COD_PERSONA
	inner join ESSALUD_PERSONA E on  E.COD_PERSONA=P.COD_PERSONA
los inner tienen la particularidad que puedes decidir que accion tomar, dependendo de que lado de la consulta se encuentre disponible, por ejemplo, si la region donde nacio la persona no existe, (que es un dato al lado derecxho de la consulta) puedes pespecificar con right join que no aparezca el registro si el dato no esta. Tb puedes hacer al contratrio con left outer join

espero te sirva de algo
slds
plch
__________________
Nada mas patetico que "detestar" a Intel o Microsoft o Windows o Apple ... apuesto que eres el tipico teton espinilluo y pajero que usa Linux para sentirse capo ...

Última edición por Porlachucha; 17/05/2010 a las 16:01 Razón: me falto especificar las clausulas del where en la consulta
  #3 (permalink)  
Antiguo 17/05/2010, 16:16
Avatar de iislas
Colaborador
 
Fecha de Ingreso: julio-2007
Ubicación: Mexico, D.F.
Mensajes: 6.482
Antigüedad: 16 años, 9 meses
Puntos: 180
Respuesta: Optimizar Consulta SQL

¿Como andamos de indices?
  #4 (permalink)  
Antiguo 18/05/2010, 08:40
 
Fecha de Ingreso: mayo-2010
Mensajes: 5
Antigüedad: 14 años
Puntos: 0
Respuesta: Optimizar Consulta SQL

gracias por la ayuda ,pero aun así estoy usando subquery para que no me consuma muchos recursos ya que son 18millones de registros (es lo que tengo entendido por teoría)
y en cuanto los indices ... tu creas que sea recomendable asignarle 1 indice por cada columna?, las búsquedas que me piden pueden ser por cualquier criterio
  #5 (permalink)  
Antiguo 18/05/2010, 09:40
Avatar de iislas
Colaborador
 
Fecha de Ingreso: julio-2007
Ubicación: Mexico, D.F.
Mensajes: 6.482
Antigüedad: 16 años, 9 meses
Puntos: 180
Respuesta: Optimizar Consulta SQL

Puedes optimizar tu consulta utlizando el wizard para crear indices, si no los tienes y ademas NO estas utilizando correctamente la funcion de DATEDIFF, entonces debes entender que el motor esta comparando tus 18 millones de registros, cada que ejecutas tu consulta. ok?
  #6 (permalink)  
Antiguo 18/05/2010, 10:37
 
Fecha de Ingreso: mayo-2010
Mensajes: 5
Antigüedad: 14 años
Puntos: 0
Respuesta: Optimizar Consulta SQL

Bueno no estoy utilizando el datediff por que me piden calcular la edad exacta de la persona(incluyendo meses y días) y con el datediff me da la edad que tiene o tendrá
y eso de Wizard nunca lo había escuchado antes , de que trata básicamente?
  #7 (permalink)  
Antiguo 18/05/2010, 12:47
Avatar de iislas
Colaborador
 
Fecha de Ingreso: julio-2007
Ubicación: Mexico, D.F.
Mensajes: 6.482
Antigüedad: 16 años, 9 meses
Puntos: 180
Respuesta: Optimizar Consulta SQL

En cuanto al calculo de la edad, ya se publico el tema correspondiente, lo puedes buscar

En cuanto al wizard para crear indices, en que ANALIZADOR DE CONSULTAS, tienes una opcion para mostrarte la sugerencia de creacion de indices en base al plan de ejecucion elaborado

Etiquetas: sql
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:24.