SQL Server - Problemas con inner join

 
Vista:

Problemas con inner join

Publicado por Gabriel Fabres (2 intervenciones) el 30/07/2008 15:55:34
Hola a todos.
tengo el siguiente problema con una consulta.

tengo el siguiente select

select mo.name,
us.usunom + ' ' + us.usuapepat as nombre_usuario,
ci.ciades as compañia,
lo.locdes as localidad,
ar.aredes as division,
cc.ccocod as centro_Costo

from modacc mo with (noLock) -- tabla con detalle
inner join usutab us on mo.name = us.name --tabla con nombres de usuario
inner join ciatab ci on mo.ciacod = ci.ciacod -- tabla con nombres de compañias
inner join loctab lo on mo.loccod = lo.loccod -- tabla con nombre de locales
inner join aretab ar on mo.divcod = ar.arecod -- tabla con nombres de divisiones
inner join ccotab cc on mo.ccocod = cc.ccocod tabla con nombres de centros de costo

where mo.name = 'qfybarra' -- usuario seleccionado
and mo.oricod = '018' -- origen de la compañia que consulta
and mo.modcod = 'WEB' -- tipo de modulo a consultar

en donde la tabla llamada modacc contiene mas de 80.000 registros con accesos de clientes a modulos de la intranet, y las tablas usutab, ciatab, loctab, aretab, y ccotab, datos especificos de usuarios, compañias, areas, locales y centros de costo respectivamente.

el problema se da en que al hacer el siguiente select de un usuario cualquiera

select * from modacc mo
where mo.name = 'qfybarra'
and mo.oricod = '018'
and mo.modcod = 'WEB'

me aparecen 2 registros (lo cual esta correcto), segun el criterio del where.

pero al hacer el mismo select usando los inner joins del comienzo, la consulta se demora varias horas, y genera miles de registros, cuando solo deberia entregar 2 registros con los datos solicitados.

como dato adicional, les puedo comentar que lamentablemente las tablas estan mal diseñadas, ya que todos los nombres de campos involucrados en esta consulta son del tipo varchar(XX), y esto no lo puedo cambiar (aun), y ademas de eso, existe mucha informacion en las tablas que esta mal (años de acumular registros)

De antemano ,muchas gracias por sus sugerencias
Saludos Cordiales.
Gabriel
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Problemas con inner join

Publicado por pacopaz (131 intervenciones) el 30/07/2008 19:28:46
Lo que puedo ver, no más de entrada, es que vinculas la tabla de Usuarios a través del nombre del usuario y, por lo que puedo imaginar, puedes tener 300 pedros o 200 alfonsos, etc, así que hay que buscar otra forma de vincularlos, sea por código de usuario, o sea con una relación más detallada.
Otra, es que el último join no lo ocupas, por que en el select traes el código del centro de costos, que ya existe en tu primera tabla.
Y por último, como sucede con la tabla de Usuarios, quizás necesites una mejor definición en las otras relaciones, para asegurar que el registro que encuentr sea el correcto.
Una forma de comprobar esto es hacer un join a la vez, para saber de donde vienen los registros excedentes y resolver de uno en uno los problemas.

Espero que te sirva.

Saludos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Gabriel Fabres

RE:Problemas con inner join

Publicado por Gabriel Fabres (4 intervenciones) el 30/07/2008 20:21:23
Hola, gracias por tu respuesta.

Respecto de tus observaciones, el campo name, en realidad es un login (unico) no se porque el que desarrollo este sistema le puso ese nombre, pero sirve como indice, aunque se repite. muchas veces en la tabla de movimientos, y eso lo solucione usando distinct
en el tema del select, lo que realmente necesitaba, era el nombre del centro de costo, ya que debera aparecer en un listado de accesos, por eso pude la descripcion.
lo otro que se me ocurrio tb, fue mejorar un poco los indices en los inner joins, de modo que pudiese afinar un poco el resultado de esas busquedas restringiendo mas el criterio de busqueda.

asi quedo el SP con las modificaciones

ALTER PROCEDURE [dbo].[__UP_WEB_GEN_LISTAR_PERMISOS_USUARIO]
@oricod varchar(15),
@user varchar(16),
@modini varchar(3)
AS
set nocount on
select distinct mo.name,
us.usunom + ' ' + us.usuapepat as nombre_usuario,
ci.ciades as compañia,
lo.locdes as localidad,
ar.aredes as division,
cc.ccocod as centro_Costo
from modacc mo with (noLock)
inner join usutab us on mo.name = us.name
inner join ciatab ci on mo.oricod = ci.oricod and mo.ciacod = ci.ciacod
inner join loctab lo on mo.oricod = lo.oricod and ci.ciacod = lo.ciacod and mo.loccod = lo.loccod
inner join aretab ar on mo.oricod = ar.oricod and mo.divcod = ar.arecod
inner join ccotab cc on mo.oricod = cc.oricod and mo.ccocod = cc.ccocod
where mo.name = @user
and mo.oricod = @oricod
and mo.modcod = @modini
return

Los tiempos de respuesta, mejoraron de varios minutos a solo un par de segundos para los usuarios con mas registros en la tabla de origen.

Gracias por tu respuesta
Saludos
Gabriel.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar