0

内部に複数のクエリがあるかなり長く複雑なクエリを最適化する必要があります。第 3 世代の SELECT として何度も繰り返されるサブクエリがあります。

(SELECT mc.cotmoneda2 FROM monedacotizaciones mc  WHERE date(mc.`FechaHora`)<= date( p.Fechacreacion) AND mc.tipo=0 order by mc.`FechaHora`desc limit 1))

完全なクエリの縮小版を次に示します。

SELECT p.ID
  ,p.Tipo
  , p.Numero
  , p.Nombre
  , e.Empresa
  ,(CASE p.NroMoneda WHEN 1 Then (SELECT sum(fi.ImportePrecio1/(SELECT mc.cotmoneda2 FROM monedacotizaciones mc  where date(mc.`FechaHora`)<= date( p.Fechacreacion) and mc.tipo=0 order by mc.`FechaHora`desc limit 1))
                                    FROM facturasitems fi inner join facturas f on (fi.idFactura= f.Recid)
                                    where (f.estado =0 or f.estado =1 or f.estado =3 ) and  f.idpedido = p.`recid`)

                       ELSE  (SELECT sum(fi.ImportePrecio2)
                             FROM facturasitems fi inner join facturas f on (fi.idFactura= f.Recid)
                             where (f.estado =0 or f.estado =1 or f.estado =3 ) and  f.idpedido = p.`recid`) end) as FacturadoUSA

  ,(SELECT sum(Ci.ImportePrecio1/(SELECT mc.cotmoneda2 FROM monedacotizaciones mc  where date(mc.`FechaHora`)<= date( p.Fechacreacion) and mc.tipo=0 order by mc.`FechaHora`desc limit 1))
     FROM Comprasitems ci inner join Compras C on (ci.idCompra= C.Recid)
     WHERE (c.estado =0 OR c.estado =1 ) AND C.idpedido = p.`recid`) as CostoRealUSA


  ,(SELECT sum(dgv.importe/(SELECT mc.cotmoneda2 FROM monedacotizaciones mc  where date(mc.`FechaHora`)<= date( p.Fechacreacion) and mc.tipo=0 order by mc.`FechaHora`desc limit 1))
    FROM detalles_gastosvarios23 dgv
    where dgv.idref = p.Recid) as GastosReales


FROM Pedidos p INNER JOIN  `contactos` ON (p.`idref`=`contactos`.`idcontacto`)
           INNER JOIN `empresas` e ON (contactos.`idempresa`= e.`idempresa`)
           INNER JOIN `talonarios` ON (`talonarios`.`recid`= p.`idtalonario`)
WHERE  (p.`fechacreacion` BETWEEN '<%fechainicio%>' AND '<%fechafin%>')
  AND talonarios.NroSucursal =1
GROUP BY p.Numero

私がやりたいことは、サブクエリを含むユーザー変数を作成して、レコードごとに再評価されるようにすることですが、レコードごとに 1 回だけです。今のやり方で動作しますが、3分以上かかります!. さまざまなオプションを何度も試しましたが、構文が正しくないようです。問題は、ユーザー変数サブクエリに p への参照が含まれていることです。

ありがとう、私の下手な英語でごめんなさい。

4

1 に答える 1

0

クエリを高速化する 1 つの方法は、一時テーブルを作成することです。他にも方法はあると思いますが、これは一つの方法です。遅くしている原因の一部は、「f.estado = 0 OR f.estado = 1 OR f.estado = 3」などのすべての条件です...何度も繰り返されます。これらの条件が満たされたレコードのリストのみが一時テーブルに含まれている場合は、処理が速くなります。

SELECT <Desired Columns>
INTO #<TableName>
FROM facturasitems fi inner join facturas f on (fi.idFactura= f.Recid)
WHERE (f.estado =0 or f.estado =1 or f.estado =3 ) and  f.idpedido = p.`recid`)

次に、クエリの1つが次のようになります

SELECT sum(fi.ImportePrecio2)
FROM #<TableName>

クエリは、毎回これらの条件をすべて調べる必要がなくなります。

于 2016-03-16T20:26:21.430 に答える