Necesito ejecutar una consulta de solo lectura, que consta a su vez de otras consultas y que encima tienen que ser parametrizadas. Hasta ahora lo único que he conseguido es un procedimiento almacenado incluyendo las subconsultas de la forma: ... FROM (SELECT...) Pero como son varias las subconsultas el procedimiento tarda bastante en ejecutar la consulta.
La verdad, que con la información que me das no sé como aconsejarte. Habría que estudiar el diseño de las tablas donde tienes la información y la consulta en concreto, para ver si se puede mejorar. Comentame un poco en que consiste y enviame un script de las tablas que intervienen y de la consulta. Con esto le echo un vistazo y te comento.
Ya lo he solucionado, pero no me gusta como queda, solo tarda 2 o 3 segundos en ejecutarse pero como tenga que hacer muchas consultas como estas me puedo morir. Trabajo con Visual Basic 6.0 y SQL SERVER 7.0 Al final cree un procedimiento almacenado, ahí va: CREATE PROCEDURE procBalanceObrasEnCurso @F_Inicio varchar(10), @F_Fin varchar(10) AS SELECT q.Ref_OrFa, ISNULL(HR.H_R,0) as H_R, ISNULL(HR.VMHR,0) as VMHR,ISNULL(H_R * VMHR,0) as PtasH_R, Mat.PtasMateriales, Fac.FacVent, q.Descripcion, q.Ptas_P, q.Empresa, TotalOF = ISNULL((HR.H_R * HR.VMHR),0)+ISNULL(Mat.PtasMateriales,0), Neto = case when ISNULL((HR.H_R * HR.VMHR),0)+ISNULL(Mat.PtasMateriales,0)+ISNULL(Fac.FacVent,0)>q.Ptas_P and q.Ptas_P>0 then q.Ptas_P- ISNULL(Fac.FacVent,0) else ISNULL((HR.H_R * HR.VMHR),0)+ISNULL(Mat.PtasMateriales,0)-ISNULL(Fac.FacVent,0) end FROM (SELECT O.Ref_OrFa, O.Descripcion, O.Ptas_P, C.Empresa, O.Ref_O, O.Día_Entrega, O.Situación_O, O.Día_Apertura FROM dbo.Ofertas O INNER JOIN dbo.Clientes C ON O.IdCliente = C.IdCliente WHERE (O.Situación_O = 'PED' OR O.Situación_O = 'GAR' OR O.Situación_O = 'ENT') AND (O.Día_Entrega > CONVERT(DATETIME, @F_Inicio, 103) OR O.Día_Entrega IS NULL) AND (O.Día_Apertura < CONVERT(DATETIME, @F_Fin, 103) OR O.Día_Apertura IS NULL)) q LEFT OUTER JOIN (SELECT q.Ref_O, SUM(facvent.bimpon * mon.cammon) AS FacVent FROM (SELECT O.Ref_OrFa, O.Descripcion, O.Ptas_P, C.Empresa, O.Ref_O, O.Día_Entrega, O.Situación_O, O.Día_Apertura FROM dbo.Ofertas O INNER JOIN dbo.Clientes C ON O.IdCliente = C.IdCliente WHERE (O.Situación_O = 'PED' OR O.Situación_O = 'GAR' OR O.Situación_O = 'ENT') AND (O.Día_Entrega > CONVERT(DATETIME, @F_Inicio, 103) OR O.Día_Entrega IS NULL) AND (O.Día_Apertura < CONVERT(DATETIME, @F_Fin, 103) OR O.Día_Apertura IS NULL)) q INNER JOIN dbo.VentasPedidos V ON q.Ref_O = V.Oferta INNER JOIN dbo.facvent ON V.RegVentasPedidos = dbo.facvent.RegVentasPedidos INNER JOIN (SELECT codmon, cammon FROM gros.dbo.comon WHERE (codemp = '006')) mon ON dbo.facvent.codmon = mon.codmon WHERE (dbo.facvent.fechafactura < CONVERT(DATETIME, '30/04/2001', 103)) GROUP BY q.Ref_O) Fac ON q.Ref_O = Fac.Ref_O LEFT OUTER JOIN (SELECT q.Ref_O, SUM(P.ImportePedido * 166.386) AS PtasMateriales FROM (SELECT O.Ref_OrFa, O.Descripcion, O.Ptas_P, C.Empresa, O.Ref_O, O.Día_Entrega, O.Situación_O, O.Día_Apertura FROM dbo.Ofertas O INNER JOIN dbo.Clientes C ON O.IdCliente = C.IdCliente WHERE (O.Situación_O = 'PED' OR O.Situación_O = 'GAR' OR O.Situación_O = 'ENT') AND (O.Día_Entrega > CONVERT(DATETIME, @F_Inicio, 103) OR O.Día_Entrega IS NULL) AND (O.Día_Apertura < CONVERT(DATETIME, @F_Fin, 103) OR O.Día_Apertura IS NULL)) q INNER JOIN dbo.PEDIDOS P ON q.Ref_O = P.Ref_O WHERE (P.F_Factura < CONVERT(DATETIME, @F_Fin, 103)) AND (P.Facturado = 1) GROUP BY q.Ref_O) Mat ON q.Ref_O = Mat.Ref_O LEFT OUTER JOIN (SELECT q.Ref_O, SUM(h.Horas) AS H_R, AVG(GFH.Precio_hora_General) AS VMHR FROM dbo.qryOFsEntPedGar q INNER JOIN dbo.Horas h ON q.Ref_O = h.Ref_O INNER JOIN dbo.Tarjetas t ON h.IdTarjeta = t.IdTarjetaTiempo INNER JOIN dbo.GFH ON h.GFH = dbo.GFH.GFH WHERE (t.FechaEntrada < CONVERT(DATETIME, @F_Fin, 103)) GROUP BY q.Ref_O) HR ON q.Ref_O = HR.Ref_O
Le he estado echando un vistazo, y por lo que veo, no hay otra solución con las tablas normalizadas. En estos casos, si te baja demasiado el rendimiento, debes denormalizar un poco y poner acumulados que te eviten ir a otras tablas. Con la consiguiente complejidad de actualización y proceso de recalculo de dichos campos (para dejarlo bien del todo). Hay casos en los que es interesante denormalizar. Sobre el tema hay un artículo muy interesante en la web de Fernando G. Guerrero (no recuerdo el nombre), a ella puedes llegar desde la mía, yendo a la sección BackOffice > SQL Server > Webs amigas.