Principales respuestas
Inner join campos no clave

Pregunta
-
Hola a todos:
Tengo problemas con una consulta . . tarda demasiado mas de 7 segundos la he revisado varias veces y me quedo con la duda de la relacion que tienen entre dos campos que no son pk
el campo que contiene la llave foranea hace referencia a un campo que no es primary key
a esto se debe el problema? . .por lo general he visto los inner join entre pk y fk sin embargo me gustaria tener sus opiniones al respecto
de antemano muchas gracias
Respuestas
-
Con permiso del resto de compañeros.
El 66 % del coste de tu consulta es simplemente recoerrer tu tabla contrato completa, Crea un índice que contenta las columnas Cod y objt en principio solamente ese.
Los joins se hacen de la forma más adecuada, con merge join, En cualquier caso probablemente un índice en la tabla supervisor por los campos cod_emp ,contract o al reves contract,cod_emp (crea ambos,mira cual usa el plan de ejecución y borras el otro). mejoren tu consulta.
Saludos
Miguel Egea
Comparte lo que sepas, aprende lo que no sepas (FGG) http://www.portalsql.com- Propuesto como respuesta Alberto López Grande (qwalgrande)Moderator miércoles, 6 de julio de 2011 15:45
- Marcado como respuesta Alberto López Grande (qwalgrande)Moderator jueves, 14 de julio de 2011 21:10
Todas las respuestas
-
Una restriccion de clave foranea puede referenciar la clave primaria, grupo de columnas que participan en una restriccion de unicidad (unique constraint), o que forman parte de un indice unico.
No puedo darte sugesrencia o explicacion alguna sobre le que te esta sucediendo, ya que no tenemos conocimientos de la estructura de las tablas, inclyendo rstricciones e indices. Asi como informacion sobre el plan de ejecucion.
AMB
-
Independientemente de que uses pk, fk o no las uses ... Ten presente que usamos operadores JOIN para mejorar el rendimiento de las consultas frente a realizar una subconsulta de una consulta...
La ventaja de crear un operador JOIN consiste en que puede evaluar tablas en un orden distinto del definido por la consulta.
La ventaja de usar una subconsulta es que normalmente no es necesario explorar todas las filas de la subconsulta para evaluar la expresión de ésta.
Por ejemplo, una subconsulta EXISTS puede devolver TRUE al ver la primera fila que coincida...
Espero me entiendas.
No sé, si preguntas por algo mas concreto, en tal caso comentanoslo.
Norman M. Pardell||Microsoft Certified IT Professional|| Database Administrator. Database Developer. SQL Server 2008
-
Hola.
No hay ninguna relación entre el rendimiento de un inner join y el hecho de que cruces claves primarias, foráneas o naturales. Lo importante es la indexación que tengas y de la consulta. ¿Puedes pasarnos la sentencia? A lo mejor podemos sugerirte la creación de un índice o la reescritura de la sentencia.
Alberto López Grande
SQL Server MVP
Visita mi blog en http://qwalgrande.blogspot.es/ Sígueme en twitter en http://twitter.com/qwalgrande -
Hola Norman, no se puede generalizar esta apreciación. No es ni cierta ni falsa, pero no tiene fundamento. Generalmente el optimizador de consultas usa planes de ejecución identicos en consultas resueltas con join o con exist, y el optimizador resuelve el orden de evaluación de tablas según el plan que elije.
En todo caso, las respuestas de norman y de alberto me parecen lo más adecuadas. nada que ver que la consulta se haga por la pk o por cualquier otra cosa, lo que importa es la consulta y la indexación para resolverla, o la forma de reescribirla para que rinda mejor.
Comparte lo que sepas, aprende lo que no sepas (FGG) http://www.portalsql.com -
-
SELECT CONTRAT.COD, CONTRAT.OBJTO, ( SELECT TOP 1 TERCERO.COD FROM SUPERVISOR INNER JOIN TERCERO ON SUPERVISOR.COD_EMP = TERCERO.COD_EMP WHERE SUPERVISOR.CONTRAT= CONTRAT.COD ) AS SUPERVISOR FROM CONTRAT
TERCERO.COD_EMP aparece como Unique Index pero tiene valores null
TERCERO.COD es el campo Primary Key
SUPERVISOR.COD_EMP es la foreign key que hace referencia a COD_EMP de tercero . . especialmente
En el plan de ejecucion me arroja un full scan y no toma el pk de tercero
El campo ID_FNCNRIO en la tabla SUPERVISOR tiene repetido por ej el id_fncnrio 1 por lo que esta columna no es unique index
- Editado Juanweb martes, 5 de julio de 2011 22:59 Anadir
-
Juanweb,
Sin intenciones de ofender, pero parece que tratas de evitar nuestra ayuda por todo lo alto.
Para evitar el dime que te dire, es preferible y de mucha ayuda, que postees la estructura de las tablas en cuestion, incluyendo restricciones e indices. Asi como el plan de ejecucion, y de ser posible una breve descripcion de lo que tratas de hacer con este query.
Como buena practica, es recomendable tener un indice que soporte la restriccion de clave foranea. Por ejemplo, si tienes una restriccion de clave foranea en la tabla [supervisor], usando la columna [cod_emp] para referenciar la tabla [tercero] y columna [cod_emp], entonces es recomendable tener un indice en la tabla [supervisor] por la columna [cod_emp].
Es dificil saber lo que tratas de hacer solo con leer el query. Al parecer tratas de traer, para cada fila en la tabla [contract], cualquier [cod_emp] de la tabla [tercero] siempre y cuando esta tenga una fila que mache en la tabla [supervisor] y que esta a su vez tenga un fila que mache con la tabla [contrat].
Que tal si pruebas:
select
C.cod,
C.objto,
max_tercero_cod
from
contract as C
inner join
(
select
S.contract,
max(T.cod) as max_tercero_cod
from
supervisor as S
inner join
tercero as T
on S.cod_emp = T.cod_emp
group by
S.contract
) as R
on C.cod = R.contract;
GO
AMB
-
ejecutando su instruccion obtengo el siguiente plan de ejecucion
la ejecucion de una subconsulta ralentiza la consulta? como lo hago en la instruccion que puse
ia cree el indice en la columna ID_FNCNRIO del supervisor
hay un table scan sobre la tabla supervisor
el join entonces se puede hacer entre el campo de la tabla supervisor y la columna de id_fncnrio de tercero . . esta columna no es pk la pk es terccod
-
Con permiso del resto de compañeros.
El 66 % del coste de tu consulta es simplemente recoerrer tu tabla contrato completa, Crea un índice que contenta las columnas Cod y objt en principio solamente ese.
Los joins se hacen de la forma más adecuada, con merge join, En cualquier caso probablemente un índice en la tabla supervisor por los campos cod_emp ,contract o al reves contract,cod_emp (crea ambos,mira cual usa el plan de ejecución y borras el otro). mejoren tu consulta.
Saludos
Miguel Egea
Comparte lo que sepas, aprende lo que no sepas (FGG) http://www.portalsql.com- Propuesto como respuesta Alberto López Grande (qwalgrande)Moderator miércoles, 6 de julio de 2011 15:45
- Marcado como respuesta Alberto López Grande (qwalgrande)Moderator jueves, 14 de julio de 2011 21:10