我的查询运行缓慢

q8l4jmvw  于 2021-06-24  发布在  Mysql
关注(0)|答案(1)|浏览(289)

选择(inv\u total-isc\u total)作为利润来源(
选择
合计(库存净重库存单价)为isc合计,
金额(如(i.“$ex\u gst.”ex\u gst='是')
then(inv.net\u weight
(i.final='y'且i.currency\u id不为空时的情况)then(ind.final\u单价cr.currency\u值)
当(i.final='y'且i.currency\u id为空)时,则ind.final\u单价
当(i.final<>'y'和i.currency\u id不为空)时,则(ind.unit\u price
cr.currency\u value)
当(i.final<>'y'和i.currency\u id为空)时,则ind.unit\u price else ind.unit\u price end)1.06)
else(inv.net\u weight
(i.final='y'且i.currency\u id不为空时的情况)然后(ind.final\u单价cr.currency\u值)
当(i.final='y'且i.currency\u id为空)时,则ind.final\u单价
当(i.final<>'y'和i.currency\u id不为空)时,则(ind.unit\u price
cr.currency\u value)
当(i.final<>'y'和i.currency\u id为空)时,则指示单价
其他工业单位(单价结束)
)结束
)作为发票合计
来自“$prefix\u qry.”库存发票
内部联接“..$prefix\u qry.”osc\u detail osc\u do on osc\u do.inventory\u id=inv.inventory\u id
inner join product p on inv.product\u id=p.product\u id
左连接“..$prefix\u qry.”isc isc on inv.isc\u batch\u no=isc.isc\u batch\u no
isc.supplier\u id=s.supplier\u id上的内部连接供应商
内部联接“..$prefix\u qry.”inv.osc\u id=i.osc\u id上的发票i
内部联接“..$prefix\u qry.”i.invoice\u id=ind.invoice\u id和ind.product\u id=p.product\u id上的invoice\u detail ind
left join currency cr on i.currency\u id=cr.currency\u id
其中inv.osc\u id!=''
库存类型='确认'
i.cancel\u by为空
和s.supplier\u id='“$supp\u id.”
月份(即交货日期)=“$月”
年份(即交货日期)=“.”年“)作为

bq9c1y66

bq9c1y661#

为了使mysql能够有效地利用索引上的范围扫描,将date\u of \u delivery作为前导列,假设$year表示有效的年份,而$month是介于1和12之间的值,那么请更改以下内容:

AND MONTH(i.date_of_delivery) = '".$month."'
     AND YEAR(i.date_of_delivery) = '".$year ."'

对这样的事情:

AND i.date_of_delivery >= STR_TO_DATE('".$year."-".$month."-01','%Y-%m-%d')
     AND i.date_of_delivery  < STR_TO_DATE('".$year."-".$month."-01','%Y-%m-%d') 
                               + INTERVAL 1 MONTH

世界的“外在” LEFT JOINisc 被后面的内部连接取反 s . 也就是说,替换 LEFT JOININNER JOIN .
确保有合适的索引可用,并且正在使用。
explain输出将显示执行计划。
除此之外,我们还需要看到explain输出。这将为我们提供一个关于哪些索引可用、表统计等等的线索。为了真正深入研究,我们需要知道查询中涉及的所有表的所有索引的定义,以及 predicate 中涉及的列的数据类型。
如果内联视图查询返回一行,则派生表的开销可以忽略不计。
此查询应返回与原始内联视图等效的结果。

SELECT SUM( inv.net_weight
          * inv.unit_price
       ) AS isc_total
     , SUM( inv.net_weight
          * IF(( i.".$ex_gst."ex_gst = 'YES' ), 1.06, 1.00)
          * IF(( i.final = 'Y' ), ind.final_unit_price, ind.unit_price)
          * IF(( i.final IS NULL OR i.currency_id IS NULL ), 1.00, cr.currency_value)
       ) AS inv_total
  FROM ".$prefix_qry."invoice i
  JOIN ".$prefix_qry."invoice_detail ind
    ON ind.invoice_id       = i.invoice_id
  JOIN ".$prefix_qry."inventory inv
    ON inv.product_id       = ind.product_id
   AND inv.inventory_type   = 'CONFIRM'
   AND inv.osc_id           = i.osc_id
   AND inv.osc_id          != ''
  JOIN ".$prefix_qry."osc_detail osc_do
    ON osc_do.inventory_id  = inv.inventory_id
  JOIN ".$prefix_qry."isc isc
    ON isc.supplier_id      = '".$supp_id."'
   AND isc.isc_batch_no     = inv.isc_batch_no
  JOIN supplier s
    ON s.supplier_id        = '".$supp_id."'
   AND s.supplier_id        = isc.supplier_id
  JOIN product p
    ON p.product_id         = inv.product_id
   AND p.product_id         = ind.product_id
  LEFT
  JOIN currency cr
    ON cr.currency_id       = i.currency_id
 WHERE i.cancel_by         IS NULL
   AND i.osc_id            != ''
   AND i.date_of_delivery  >= DATE_FROM_STR('".$year."-".$month."-01','%Y-%m-%d')
   AND i.date_of_delivery   < DATE_FROM_STR('".$year."-".$month."-01','%Y-%m-%d')
                              + INTERVAL 1 MONTH

选择列表中列用法的摘要

-------- ---------------------------------------------------------------
i        final, currency_id, $[ex_gst]ex_gst
inv      net_weight,unit_price
cr       currency_value

predicate 中的列用法摘要

-------- ---------------------------------------------------------------
i        osc_id, invoice_id, cancel_by, date_of_delivery
ind      invoice_id
inv      inventory_id, isc_batch_no, osc_id, inventory_type, product_id
isc      isc_batch_no, supplier_id
osc_do   inventory_id
p        product_id
s        supplier_id
cr       currency_id

这些表可能较小,并且已经将这些列作为主键

... ON p       (product_id)
... ON s       (supplier_id)
... ON cr      (currency_id)

我们应该考虑是否有必要包括 product ( p )以及 supplier ( s )查询中的表。如果使用的列(如上所示)用于 p 以及 s 是主键或唯一键,如果强制执行这些外键约束:

inv (product_id)  references p (product_id)
 ind (product_id)  references p (product_id)
 isc (supplier_id) references s (supplier_id)

然后连接到 p 以及 s 不会影响结果。也就是说,这些表可以从查询中删除。
覆盖索引的第一个切入点可能有助于优化器生成有效的执行计划。。。

... ON i       (date_of_delivery,cancel_by,osc_id,invoice_id,final,currency_id,[$ex_gst]ex_gst)
... ON ind     (invoice_id, product_id)
... ON inv     (inventory_id,inventory_type,isc_batch_no,osc_id,inventory_type,product_id,net_weight,unit_price)
... ON isc     (supplier_id,isc_batch_no)
... ON osc_do  (inventory_id)

相关问题