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

Duda al crear los índices correctos a fin de optimizar

Estas en el tema de Duda al crear los índices correctos a fin de optimizar en el foro de SQL Server en Foros del Web. Bueno, agradezco de antemano a quien me colabore en este tema. Me ha tocado tener que optimizar algunas consultas que se tardan demasiado e investigando ...
  #1 (permalink)  
Antiguo 29/01/2008, 14:49
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 23 años
Puntos: 146
Duda al crear los índices correctos a fin de optimizar

Bueno, agradezco de antemano a quien me colabore en este tema. Me ha tocado tener que optimizar algunas consultas que se tardan demasiado e investigando considero que puede ayudarme mucho el crear algún tipo de índice (no estoy seguro aún cual es que mejor se acomode a mi problema). Tengo el SQL Server 2005 WorkGroup y no tiene el Data Engine Tuning Advisor.

Les explico la situación:

Tengo esta vista:

Código:
SELECT     ro.IDPlanta, gr.CodigoCliente AS Grupo, ro.IDMolino, c.CodigoCliente AS Cliente, ro.IDRollo, ro.NoMaster, ro.NoCase, ro.NoInspeccion, 
                      ro.NoProcesador, ro.NoParte, ro.Revision, ro.IDEspecificacion AS Spec, ro.Dimension, ro.Peso, CONVERT(varchar, ro.Posicion) 
                      + '/' + CONVERT(varchar, ro.Cortes) AS Corte, ro.FechaRecepcion, ro.FechaCorte, ro.FechaEntrega, CONVERT(varchar, re.NoRemision) AS NoRemision, 
                      ro.Barco, ro.NoViaje, ro.NoFacturaCompra, ro.CostoMXP, ro.CostoUSD, CAST(re.NoFacturaVenta AS varchar) AS NoFacturaVenta, ro.Espesor, ro.Ancho, 
                      ro.Largo, ro.Proceso, ro.IDCliente, ro.RolloPadre, ro.IDMaterial, rd.IDUsuario, rd.TimeStamp, ro.Pedimento, ro.FechaPedimento, ro.Fraccion, ro.Piezas, 
                      re.IDConsignatario, co.NombreCorto AS NombreConsignatario, re.Tipo, op.Nombre AS Operador, re.Observaciones, ro.IDProveedor, ro.CostoFactura, 
                      ro.FechaFacturaCompra, ro.Lote
FROM         dbo.RollosEmbarque AS ro INNER JOIN
                      dbo.Clientes AS c ON ro.IDCliente = c.IDCliente INNER JOIN
                      dbo.Clientes AS gr ON c.IDGrupo = gr.IDCliente INNER JOIN
                      dbo.RemisionesDetalle AS rd ON ro.IDRollo = rd.IDRollo INNER JOIN
                      dbo.Remisiones AS re ON re.NoRemision = rd.NoRemision LEFT OUTER JOIN
                      dbo.Consignatarios AS co ON re.IDConsignatario = co.IDConsignatario LEFT OUTER JOIN
                      dbo.Operadores AS op ON re.IDOperador = op.IDOperador
WHERE     (re.Estatus = 'C') AND (ro.IDPlanta NOT IN ('APRAMOS', 'APSLP', 'LAGERMEX-PUE', 'LAGERMEX-SAL')) AND (YEAR(re.Fecha) IN (2007, 2008))
UNION ALL
SELECT     s.IDPlanta, gr.CodigoCliente AS Grupo, ro.IDMolino, c.CodigoCliente AS Cliente, ro.IDRollo, ro.NoMaster, ro.NoCase, ro.NoInspeccion, ro.NoProcesador, 
                      ro.NoParte, ro.Revision, ro.IDEspecificacion AS Spec, ro.Dimension, ro.Peso, CONVERT(varchar, ro.Posicion) + '/' + CONVERT(varchar, ro.Cortes) 
                      AS Corte, ro.FechaRecepcion, ro.FechaCorte, s.Fecha AS FechaEntrega, s.Referencia AS NoRemision, ro.Barco, ro.NoViaje, ro.NoFacturaCompra, 
                      ro.CostoMXP, ro.CostoUSD, ro.NoFacturaVenta, ro.Espesor, ro.Ancho, ro.Largo, 0 AS Proceso, s.IDCliente, ro.RolloPadre, ro.IDMaterial, s.IDUsuario, 
                      s.TimeStamp, '' AS Pedimento, NULL AS FechaPedimento, '' AS Fraccion, ro.Piezas, 0 AS IDConsignatario, (CASE WHEN (s.Referencia LIKE 'TP%') 
                      THEN 'ACERO PRIME RAMOS' ELSE '' END) AS NombreConsignatario, (CASE WHEN s.Referencia LIKE 'TP%' THEN 'T' ELSE 'V' END) AS Tipo, 
                      'EDI' AS Operador, '' AS Observaciones, ro.IDProveedor, ro.CostoFactura, ro.FechaFacturaCompra, ro.Lote
FROM         dbo.Salidas AS s INNER JOIN
                      dbo.RollosEmbarque AS ro ON s.IDRollo = ro.IDRollo INNER JOIN
                      dbo.Clientes AS c ON s.IDCliente = c.IDCliente INNER JOIN
                      dbo.Clientes AS gr ON c.IDGrupo = gr.IDCliente
WHERE     (s.Referencia NOT LIKE 'T[AM]%') AND (s.IDPlanta IN ('APRAMOS', 'APSLP', 'LAGERMEX-PUE', 'LAGERMEX-SAL'))
Los mensajes que regresa al colocar set statistics io on es:
Código:
(115729 filas afectadas)
Tabla 'Worktable'. Recuento de exploraciones 0, lecturas lógicas 0, lecturas físicas 0, lecturas anticipadas 0, lecturas lógicas de LOB 0, lecturas físicas de LOB 0, lecturas anticipadas de LOB 0.
Tabla 'Salidas'. Recuento de exploraciones 1, lecturas lógicas 2595, lecturas físicas 0, lecturas anticipadas 0, lecturas lógicas de LOB 0, lecturas físicas de LOB 0, lecturas anticipadas de LOB 0.
Tabla 'RollosEmbarque'. Recuento de exploraciones 2, lecturas lógicas 50470, lecturas físicas 0, lecturas anticipadas 1, lecturas lógicas de LOB 0, lecturas físicas de LOB 0, lecturas anticipadas de LOB 0.
Tabla 'Clientes'. Recuento de exploraciones 4, lecturas lógicas 32, lecturas físicas 0, lecturas anticipadas 0, lecturas lógicas de LOB 0, lecturas físicas de LOB 0, lecturas anticipadas de LOB 0.
Tabla 'RemisionesDetalle'. Recuento de exploraciones 1, lecturas lógicas 2071, lecturas físicas 0, lecturas anticipadas 0, lecturas lógicas de LOB 0, lecturas físicas de LOB 0, lecturas anticipadas de LOB 0.
Tabla 'Remisiones'. Recuento de exploraciones 1, lecturas lógicas 283, lecturas físicas 0, lecturas anticipadas 0, lecturas lógicas de LOB 0, lecturas físicas de LOB 0, lecturas anticipadas de LOB 0.
Tabla 'Consignatarios'. Recuento de exploraciones 1, lecturas lógicas 5, lecturas físicas 0, lecturas anticipadas 0, lecturas lógicas de LOB 0, lecturas físicas de LOB 0, lecturas anticipadas de LOB 0.
Tabla 'Operadores'. Recuento de exploraciones 1, lecturas lógicas 2, lecturas físicas 0, lecturas anticipadas 0, lecturas lógicas de LOB 0, lecturas físicas de LOB 0, lecturas anticipadas de LOB 0.
Por lo cual supongo debo de agregar un índice cubierto, pero no estoy seguro sobre que campos.

Las estructuras de las tablas con más lecturas son:

Salidas
Cita:
Key->IDRollo varchar(11) Unchecked
Key->IDPlanta varchar(50) Unchecked
Key->Fecha datetime Unchecked
Key->IDCliente smallint Unchecked
Key-> Referencia varchar(50) Unchecked
IDUsuario smallint Unchecked
TimeStamp datetime Unchecked
RollosEmbarque
Cita:
Key-> IDRollo varchar(20) Unchecked
Estatus char(1) Unchecked
IDCliente smallint Unchecked
IDPropietario smallint Checked
IDProveedor varchar(50) Checked
IDMolino varchar(50) Unchecked
IDPlanta varchar(50) Unchecked
..... y como 20 campos mas
RemisionesDetalle
Cita:
Key-> NoRemision int Unchecked
Key-> IDRollo varchar(11) Unchecked
NoParte varchar(50) Checked
Revision smallint Checked
Partida smallint Checked
IDUsuario smallint Unchecked
TimeStamp datetime Unchecked
Aprovechando, también leyendo, encontré que podría hacer un índice sobre la vista en cuestión cuando se consulta muchas veces, y aunque esto no sea el camino que tomaré (por que un par de las tablas que tiene esa vista se actualizan muy constantemente y al parecer en este caso hacer esto sería contraproducente) me extraña el hecho de que marca error al hacerlo:

CREATE unique clustered INDEX clidx_vw_Entregas ON Entregas(IdCliente, IdGrupo, IdRollo);

Error: No se puede crear índice en la vista 'Entregas' porque la vista no está enlazada a ningún esquema.


Espero puedan ayudarme a entender esta teoría, gracias
  #2 (permalink)  
Antiguo 29/01/2008, 17:43
Avatar de iislas
Colaborador
 
Fecha de Ingreso: julio-2007
Ubicación: Mexico, D.F.
Mensajes: 6.482
Antigüedad: 17 años, 5 meses
Puntos: 180
Re: Duda al crear los índices correctos a fin de optimizar

Bueno, un comentario en cuanto a la cracion de INDICES, hay una teoria que dice, "Todas las columnas, despues de la instruccion WHERE, son candidatas a ser INDICES".

En cuanto a la cracion de INDICES sobre vistas, existen ciertas reglas que se deben cumplir:

Por ejemplo: "La vista debe definirse con SCHEMABINDING para crear un índice en ella"

Te sugiero leas en tu ayuda, CREATE INDEX
  #3 (permalink)  
Antiguo 29/01/2008, 18:33
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 23 años
Puntos: 146
Re: Duda al crear los índices correctos a fin de optimizar

Bueno, gracias a tu comentario supe las reglas que se deben cumplir y veo que no se pude indizar ya que necesito hacer dos vistas de esta y además no puedo tener la misma tabla dos veces en la misma vista. Necesitaría cambiarla por completo.

Ahora, referente a la primer parte de la pregunta original, espero que alguien pueda brindarme algo de ayuda con esto de crearle índices a las tablas individuales que forman esta consulta. Estoy un poco confundido con tanto material.

Gracias
  #4 (permalink)  
Antiguo 29/01/2008, 19:53
Avatar de Beakdan  
Fecha de Ingreso: diciembre-2001
Ubicación: Monterrey, Nuevo León
Mensajes: 433
Antigüedad: 23 años
Puntos: 7
Re: Duda al crear los índices correctos a fin de optimizar

En lo personal no creo que sea muy cierta esa teoría. No creo que haya reglas universales para la creación de índices.

En el caso de esta consulta... Segun los resultados de statistics io la tabla mayor es RollosEmbarque. Pero no tienes casi ninguna condición para delimitar los resultados de dicha tabla.
En la primera parte, la única condición que tienes para discriminarlos registros de RollosEmbarque es:

ro.IDPlanta NOT IN ('APRAMOS', 'APSLP', 'LAGERMEX-PUE', 'LAGERMEX-SAL')

Lo cual seguramente está generando un Index Scan debido al not in, y para lo cuál no sabría darte opciones.

El otro argumento que podría delimitar la cantidad de registros buscados en RollosEmbarque despues del join con RemisionesDetalle y Remisiones es:
YEAR(re.Fecha) IN (2007, 2008) Lo cual también generará un table o index scan, pero el volumen de esta tabla es muy reducido comparado con la anterior. Aún así, podría mejorar un poco el tiempo de respuesta (en caso de que exista un índice en este campo) cambiandolo por

re.Fecha >= '20070101' and re.Fecha < '20090101'

En la segunda parte, Salidas parece ser efectivamente el cuello de botella. Con certeza el plan de ejecución te muestra un index scan. Sin embargo, un indice de cobertura para esta consulta resultaría en un índice que usa todas las columnas disponibles en la tabla, algo que no es muy lógico, porque terminarias usando el doble de espacio de almacenamiento.
Sin embargo, sí parece lógico tener un índice en (IDPlanta, IDRollo). No incluyo "referencia", porque de todas maneras terminaría haciendo un scan ya que usa "not like".

No sabría sugerirte nada más, a menos que vea el plan de ejecución. Ya que estás optimizando, activa "set showplan_text on" y publica el plan de cada consulta en la unión. Nos dará una mejor perspectiva
  #5 (permalink)  
Antiguo 01/02/2008, 08:57
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 23 años
Puntos: 146
Re: Duda al crear los índices correctos a fin de optimizar

Siempre práctico en tus comentarios, te los agradezco y aprecio.

Bueno, después de seguir leyendo sobre la teoría de los índices y de constatar que en la tabla SALIDAS tengo duplicados en IdPlanta e IdRollo, incluso con IdCliente, y de saber por tus palabras que incluir Referencia en el índice haría que no serviera de mucho, creo que lo mejor que puedo hacer es re-hacer esa consulta, incluso modificar un poco los sistemas; de igual forma he investigado el contenido de los campos y veo que se puede aliminar esa búsqueda con LIKE sobre el campo Referencia, ya tiene datos compuestos, ya que los prefijos de la misma dicen que tipo de movimiento, voy a agregar un campo tipo y así podré indizar este campo.

De igual forma me he enterado que posiblemente ese UNION no sea necesario ya que en salidas estan todos los registros y en la tabla Remisiones estan registros que también estan en Salidas. En fin, voy a cambiarles por completo esta consulta y espero que se acelere el tiempo de respuesta, Salidas y RollosEmbarque tienen más del medio millón de registros c/u.

Te dejo de igual forma las salidas del SHOWPLAN_TEXT de c/u por si observas algo que pueda yo pasar por alto. Gracias nuevamente.

De la primer consulta:

Código:
  |--Hash Match(Right Outer Join, HASH:([op].[IDOperador])=([re].[IDOperador]), RESIDUAL:([Pruebas].[dbo].[Remisiones].[IDOperador] as [re].[IDOperador]=[Pruebas].[dbo].[Operadores].[IDOperador] as [op].[IDOperador]))
       |--Clustered Index Scan(OBJECT:([Pruebas].[dbo].[Operadores].[PK_Operadores] AS [op]))
       |--Hash Match(Right Outer Join, HASH:([co].[IDConsignatario])=([re].[IDConsignatario]), RESIDUAL:([Pruebas].[dbo].[Remisiones].[IDConsignatario] as [re].[IDConsignatario]=[Pruebas].[dbo].[Consignatarios].[IDConsignatario] as [co].[IDConsignatario]))
            |--Clustered Index Scan(OBJECT:([Pruebas].[dbo].[Consignatarios].[PK_Consignatarios] AS [co]))
            |--Hash Match(Inner Join, HASH:([gr].[IDCliente])=([c].[IDGrupo]), RESIDUAL:([Pruebas].[dbo].[Clientes].[IDGrupo] as [c].[IDGrupo]=[Pruebas].[dbo].[Clientes].[IDCliente] as [gr].[IDCliente]))
                 |--Index Scan(OBJECT:([Pruebas].[dbo].[Clientes].[IX_Clientes] AS [gr]))
                 |--Hash Match(Inner Join, HASH:([c].[IDCliente])=([ro].[IDCliente]))
                      |--Clustered Index Scan(OBJECT:([Pruebas].[dbo].[Clientes].[PK_Clientes] AS [c]))
                      |--Hash Match(Inner Join, HASH:([re].[NoRemision])=([rd].[NoRemision]))
                           |--Compute Scalar(DEFINE:([Expr1015]=CONVERT(varchar(30),[Pruebas].[dbo].[Remisiones].[NoRemision] as [re].[NoRemision],0), [Expr1016]=CONVERT(varchar(30),[Pruebas].[dbo].[Remisiones].[NoFacturaVenta] as [re].[NoFacturaVenta],0)))
                           |    |--Clustered Index Scan(OBJECT:([Pruebas].[dbo].[Remisiones].[PK_Remisiones] AS [re]), WHERE:([Pruebas].[dbo].[Remisiones].[Fecha] as [re].[Fecha]>='2007-01-01 00:00:00.000' AND [Pruebas].[dbo].[Remisiones].[Fecha] as [re].[Fecha]<'2009-01-01 00:00:00.000' AND [Pruebas].[dbo].[Remisiones].[Estatus] as [re].[Estatus]='C'))
                           |--Hash Match(Inner Join, HASH:([rd].[IDRollo])=([ro].[IDRollo]), RESIDUAL:([Pruebas].[dbo].[RollosEmbarque].[IDRollo] as [ro].[IDRollo]=[Pruebas].[dbo].[RemisionesDetalle].[IDRollo] as [rd].[IDRollo]))
                                |--Clustered Index Scan(OBJECT:([Pruebas].[dbo].[RemisionesDetalle].[PK_RemisionesDetalle] AS [rd]))
                                |--Compute Scalar(DEFINE:([Expr1014]=(CONVERT(varchar(30),[Pruebas].[dbo].[RollosEmbarque].[Posicion] as [ro].[Posicion],0)+'/')+CONVERT(varchar(30),[Pruebas].[dbo].[RollosEmbarque].[Cortes] as [ro].[Cortes],0)))
                                     |--Clustered Index Scan(OBJECT:([Pruebas].[dbo].[RollosEmbarque].[PK_RollosEmbarque] AS [ro]), WHERE:([Pruebas].[dbo].[RollosEmbarque].[IDPlanta] as [ro].[IDPlanta]<>'APRAMOS' AND [Pruebas].[dbo].[RollosEmbarque].[IDPlanta] as [ro].[IDPlanta]<>'APSLP' AND [Pruebas].[dbo].[RollosEmbarque].[IDPlanta] as [ro].[IDPlanta]<>'LAGERMEX-PUE' AND [Pruebas].[dbo].[RollosEmbarque].[IDPlanta] as [ro].[IDPlanta]<>'LAGERMEX-SAL'))
De la segunda consulta:
Código:
  |--Compute Scalar(DEFINE:([Expr1009]=(0), [Expr1010]='', [Expr1011]=NULL, [Expr1012]='', [Expr1013]=(0), [Expr1016]='EDI', [Expr1017]=''))
       |--Hash Match(Inner Join, HASH:([gr].[IDCliente])=([c].[IDGrupo]), RESIDUAL:([Pruebas].[dbo].[Clientes].[IDGrupo] as [c].[IDGrupo]=[Pruebas].[dbo].[Clientes].[IDCliente] as [gr].[IDCliente]))
            |--Index Scan(OBJECT:([Pruebas].[dbo].[Clientes].[IX_Clientes] AS [gr]))
            |--Hash Match(Inner Join, HASH:([c].[IDCliente])=([s].[IDCliente]))
                 |--Clustered Index Scan(OBJECT:([Pruebas].[dbo].[Clientes].[PK_Clientes] AS [c]))
                 |--Merge Join(Inner Join, MERGE:([ro].[IDRollo])=([s].[IDRollo]), RESIDUAL:([Pruebas].[dbo].[Salidas].[IDRollo] as [s].[IDRollo]=[Pruebas].[dbo].[RollosEmbarque].[IDRollo] as [ro].[IDRollo]))
                      |--Compute Scalar(DEFINE:([Expr1008]=(CONVERT(varchar(30),[Pruebas].[dbo].[RollosEmbarque].[Posicion] as [ro].[Posicion],0)+'/')+CONVERT(varchar(30),[Pruebas].[dbo].[RollosEmbarque].[Cortes] as [ro].[Cortes],0)))
                      |    |--Clustered Index Scan(OBJECT:([Pruebas].[dbo].[RollosEmbarque].[PK_RollosEmbarque] AS [ro]), ORDERED FORWARD)
                      |--Compute Scalar(DEFINE:([Expr1014]=CASE WHEN [Pruebas].[dbo].[Salidas].[Referencia] as [s].[Referencia] like 'TP%' THEN 'ACERO PRIME RAMOS' ELSE '' END, [Expr1015]=CASE WHEN [Pruebas].[dbo].[Salidas].[Referencia] as [s].[Referencia] like 'TP%' THEN 'T' ELSE 'V' END))
                           |--Clustered Index Scan(OBJECT:([Pruebas].[dbo].[Salidas].[PK_Salidas] AS [s]),  WHERE:(NOT [Pruebas].[dbo].[Salidas].[Referencia] as [s].[Referencia] like 'T[AM]%' AND ([Pruebas].[dbo].[Salidas].[IDPlanta] as [s].[IDPlanta]='APRAMOS' OR [Pruebas].[dbo].[Salidas].[IDPlanta] as [s].[IDPlanta]='APSLP' OR [Pruebas].[dbo].[Salidas].[IDPlanta] as [s].[IDPlanta]='LAGERMEX-PUE' OR [Pruebas].[dbo].[Salidas].[IDPlanta] as [s].[IDPlanta]='LAGERMEX-SAL')) ORDERED FORWARD)
  #6 (permalink)  
Antiguo 01/02/2008, 20:30
Avatar de Beakdan  
Fecha de Ingreso: diciembre-2001
Ubicación: Monterrey, Nuevo León
Mensajes: 433
Antigüedad: 23 años
Puntos: 7
Re: Duda al crear los índices correctos a fin de optimizar

Analizando tu plan de ejecución, por lo menos para la primera parte vemos varias cosas:

Aunque existen índices en las tablas, estos no parecen usarse adecuadamente, ya que todas las operaciones realizadas en el plan son INDEX SCAN. Dichas operaciones SCAN son consecuencia de que las operaciones de JOIN se hagan con HASH.

En el caso de la tabla RollosEmbarque probablemente no se pueda evitar hacer el JOIN con HASH, y es probablemente la mejor opción si la tabla es muy muy grande, pero podemos restringir la cantidad de registros en juego en la operación ejecutando primero los JOINS que no dependen de dicha tabla.

Podemos agrupar dbo.Remisiones, dbo.RemisionesDetalle, dbo.Consignatarios y dbo.Operadores en una subconsulta para obtener IDRollo. Ya que este es el vínculo con RollosEmbarque, y suponiendo que los IDRollo obtenidos sean menos que los que existen en RollosEmbarque, se podría ganar tiempo de ejecución.

El último paso sería vincular los datos del self-join de la tabla Clientes. Estos no limitan la búsqueda, son meramente informativos. Pero podríamos evitar hacer un HASH JOIN que aunque eficaces para tablas muy grandes, son inadecuados para tablas pequeñas como parece serlo esta tabla. Deberíamos esperar un LOOP JOIN como mejor opción.

Sin embargo, el tiempo total de respuesta no será mejor nunca que el tiempo total que tarde en devolver de la tabla RollosEmbarque los registros donde IDRollo coincida con los registros IDRollo de RemisionesDetalle.

Según parece, defines el cluster index en función del PK de las tablas asi que...

Remisiones debería tener un índice en Fecha y Estatus.

CREATE NONCLUSTERED INDEX IX_Remisiones_K_Fecha_Estatus
ON dbo.Remisiones(Fecha, Estatus)

RemisionesDetalle debería tener un índice en NoRemision (ya lo tiene si NoRemision es el primer campo del cluster index)
En ese caso, Operadores no debería tener problemas.


Debería haber un índice en la columna IDGrupo de Clientes. En esta consulta puede resultar benéfico incluir CodigoCliente en el índice(Fat Index):
CREATE NONCLUSTERED INDEX IX_CLIENTES_K_IDGrupo_CCodigoCliente
ON dbo.Clientes(IDGrupo)
INCLUDE(CodigoCliente)

RollosEmbarque ya tiene un indice adecuado en IDRollo (es la clave del cluster index)

Código:
SELECT        ro.IDPlanta, cl.Grupo, ro.IDMolino, cl.Cliente,
            ro.IDRollo, ro.NoMaster, ro.NoCase, ro.NoInspeccion,
            ro.NoProcesador, ro.NoParte, ro.Revision,
            ro.IDEspecificacion AS Spec, ro.Dimension, ro.Peso,
            CONVERT(varchar, ro.Posicion) + '/' + CONVERT(varchar, ro.Cortes) AS Corte,
            ro.FechaRecepcion, ro.FechaCorte, ro.FechaEntrega,
            CONVERT(varchar, re.NoRemision) AS NoRemision,
            ro.Barco, ro.NoViaje, ro.NoFacturaCompra, ro.CostoMXP, ro.CostoUSD,
            CAST(re.NoFacturaVenta AS varchar) AS NoFacturaVenta,
            ro.Espesor, ro.Ancho, ro.Largo, ro.Proceso,
            ro.IDCliente, ro.RolloPadre, ro.IDMaterial,
            re.IDUsuario, re.TimeStamp, ro.Pedimento,
            ro.FechaPedimento, ro.Fraccion, ro.Piezas, 
            re.IDConsignatario, re.NombreConsignatario,
            re.Tipo, re.Operador, re.Observaciones,
            ro.IDProveedor, ro.CostoFactura, ro.FechaFacturaCompra, ro.Lote
FROM        dbo.RollosEmbarque AS ro
INNER JOIN    (
                SELECT        z.IDRollo,
                            z.IDUsuario,
                            z.TimeStamp,
                            y.NoRemision,
                            y.NoFacturaVenta,
                            y.IDConsignatario,
                            y.Tipo,
                            y.Observaciones,
                            x.NombreCorto AS NombreConsignatario,
                            w.Nombre AS Operador
                FROM        dbo.Remisiones AS y
                INNER JOIN    dbo.RemisionesDetalle AS z
                            ON y.NoRemision = z.NoRemision
                LEFT JOIN    dbo.Consignatarios AS x
                            ON y.IDConsignatario = x.IDConsignatario
                LEFT JOIN    dbo.Operadores AS w
                            ON y.IDOperador = w.IDOperador
                WHERE        y.Estatus = 'C' 
                            AND y.Fecha >= '20070101'
                            AND y.Fecha < '20090101'
            ) AS re
            ON ro.IDRollo = re.IDRollo
INNER JOIN    (
                SELECT        u.IDCliente,
                            u.CodigoCliente AS Cliente,
                            v.CodigoCliente AS Grupo
                FROM        dbo.Clientes AS v
                INNER JOIN    dbo.Clientes AS u
                            ON u.IDGrupo = v.IDCliente
            ) AS cl
            ON ro.IDCliente = cl.IDCliente
WHERE        ro.IDPlanta NOT IN ('APRAMOS', 'APSLP', 'LAGERMEX-PUE', 'LAGERMEX-SAL')
Espero que te pueda servir, checa que el plan de ejecución cambie. Y que se hayan reducido las operaciones IO.

Última edición por Beakdan; 06/02/2008 a las 22:36
  #7 (permalink)  
Antiguo 16/01/2009, 11:25
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 23 años
Puntos: 146
Respuesta: Duda al crear los índices correctos a fin de optimizar

Recién encuentro este mensaje y caigo en cuenta de que nunca regresé a él a agradecerte Beakdan, me sirvió mucho tu ayuda

Gracias nuevamente, aunque tarde, por tomarte el tiempo de tan completas ayudas
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 00:25.