Mysql 优化了这个查询

Mysql 优化了这个查询,mysql,Mysql,有三张桌子的结构 Table min consist of matcode,min_qty,jo_no,mr_no Table min_out_body consist of matcode,out_qty,jo_no,mr_no Table eu_min_out_body consist of matcode,out_qty,jo_no,mr_no 数据如下: [min] matcode min_qty jo_no mr_no xxx

有三张桌子的结构

Table min consist of matcode,min_qty,jo_no,mr_no
Table min_out_body consist of matcode,out_qty,jo_no,mr_no
Table eu_min_out_body consist of matcode,out_qty,jo_no,mr_no
数据如下:

[min]
matcode       min_qty           jo_no           mr_no
xxx           100               1A              A11
xxx           150               2A              A22

[min_out_body]
matcode       out_qty           jo_no           mr_no
xxx           10                1A              A11
xxx           60                1A              A11
xxx           100               2A              A22

[eu_min_out_body]
matcode       out_qty           jo_no           mr_no
xxx           20                1A              A11
xxx           50                2A              A22
我想要达到的是一个结果:

matcode        min_qty          jo_no           mr_no          balance
xxx            100              1A              A11            10
xxx            150              2A              A22            0
使用以下代码查询:

SELECT
    min.matcode,
    min.min_qty,
    min.jo_no,
    min.mr_no
    (min.min_qty-(
        select ifnull(sum(out_qty),0) 
        FROM min_out_body 
        WHERE matcode=min.matcode 
        and jo_no=min.jo_no 
        and mr_no=min.mr_no
        )-(
        select ifnull(sum(out_qty),0) 
        FROM eu_min_out_body 
        WHERE matcode=min.matcode 
        and jo_no=min.jo_no 
        and mr_no=min.mr_no
        )
    ) as balance
FROM min
WHERE min.matcode = 'xxx'
    and (min.min_qty - (select
              ifnull(sum(out_qty),0)
            FROM min_out_body
            WHERE matcode = min.matcode
                and jo_no = min.jo_no
                and mr_no = min.mr_no) - (select
                            ifnull(sum(out_qty),0)
                              FROM eu_min_out_body
                              WHERE matcode = min.matcode
                              and jo_no = min.jo_no
                              and mr_no = min.mr_no)) > 0

我可以得到结果,但有没有办法简化查询并减少处理时间?

我看到两个选项,根据您处理的数据量,它们的性能可能会比其他方法更好。。。第一个更易于阅读,但简化了WHERE子句,并且可能是您想要使用的

包装您的查询,但仅限于WHERE MAT_代码限定符。让PQ预查询返回所有内容-所有余额。然后,只需在WHERE子句中再次应用WHERE balance>0与复杂的余额计算

SELECT PQ.*
   from
      ( SELECT
            min.matcode,
            min.min_qty,
            min.jo_no,
            min.mr_no
            (min.min_qty 
              - ( select ifnull(sum(out_qty),0) 
                    FROM min_out_body 
                   WHERE min_no = min.min_no 
                     and matcode = min.matcode 
                     and jo_no = min.jo_no 
                     and mr_no = min.mr_no )
              - ( select ifnull(sum(out_qty),0) 
                    FROM eu_min_out_body 
                   WHERE min_no=min.min_no 
                     and matcode=min.matcode 
                     and jo_no=min.jo_no 
                     and mr_no=min.mr_no ) ) as balance
           FROM 
              min
           WHERE 
                  min.matcode = 'xxx' ) PQ
   where
      balance > 0
如果数据集更大,它看起来会更大一些,因为它会根据内部字段选择要处理的组件对每个out_body表和组预聚合查询一次。然后左键连接到那些表。这种方法的好处是,它不会在每个记录的基础上运行内部select sum,如果您有1000个记录要处理,可能会为您节省更多的时间。。。特别是当它通过MIN_OUT_BODY和EU_MIN_OUT_BODY时

通过左连接,它要么是它们的,要么不是,IFNULL以同样的方式工作,那么WHERE子句就是相同的简单可读的余额计算,而无需再次查询

SELECT
      min.matcode,
      min.min_qty,
      min.jo_no,
      min.mr_no,
      min.min_qty - ifnull( MOB1.out_qty, 0 ) - ifnull( EMOB1.out_qty, 0 ) balance
   from
      min
         LEFT JOIN ( select 
                      mob.matcode,
                      mob.min_no,
                      mob.jo_no,
                      mob.mr_no,
                      SUM( mob.out_qty ) out_qty
                   from
                      min_out_body mob
                   where
                      mob.matcode = 'xxx'
                   group by
                      mob.matcode,
                      mob.min_no,
                      mob.jo_no,
                      mob.mr_no ) MOB1
            ON min.matcode = MOB1.matcode
            AND min.min_no = MOB1.min_no
            AND min.jo_no = MOB1.jo_no
            AND min.mr_no = MOB1.mr_no 

         LEFT JOIN ( select 
                      Emob.matcode,
                      Emob.min_no,
                      Emob.jo_no,
                      Emob.mr_no,
                      SUM( Emob.out_qty ) out_qty
                   from
                      eu_min_out_body Emob
                   where
                      Emob.matcode = 'xxx'
                   group by
                      Emob.matcode,
                      Emob.min_no,
                      Emob.jo_no,
                      Emob.mr_no ) EMOB1
            ON min.matcode = EMOB1.matcode
            AND min.min_no = EMOB1.min_no
            AND min.jo_no = EMOB1.jo_no
            AND min.mr_no = EMOB1.mr_no 
   where
          min.matcode = 'xxx'
      AND min.min_qty - ifnull( MOB1.out_qty, 0 ) - ifnull( EMOB1.out_qty, 0 ) > 0

你在桌子上用的钥匙是什么?对于表,您使用的是什么引擎?引擎是myisam,对于表min,键是matcode、jo_no和wr,对于其他两个表,键实际上是doc_no,这两个查询都尝试过了。第一个查询返回的结果与我在上面发布的查询相同,并在7秒左右进行了优化。对于第二个查询,Mine是29秒,有1329个数据,它的速度完全疯狂,它可以处理1.524.742数据仅7秒,但结果不是预期的。预期结果应仅为1329数据。@user3077209您应该将表结构和一些示例数据发布到。。。没有这些基本信息的SQL优化就像没有鱼竿钓鱼,答案将基于猜测…@user3077209,我不知道你是否用matcode修复了我糟糕的mat_代码,但我更新了查询以获得正确的列名引用。如果问题是matcode,请重试查询。。。至于您对1.524.742的引用,我省略了matcode='xxx'的外部WHERE子句。。。请参阅修订并重试。@DRapp太棒了,需要0.047秒才能获得与预期相同的结果。另一个问题,通过使用第二个查询,如何从min表中的所有matcode中获取当前样本,因为它随matcode一起提供,我的意思是我们将min_out_body和eu_min_out_body中的matcode引用到min表。@user3077209,我不明白,但如果您作为另一个问题发布并显示样本数据,邮寄时给我一张便条,我也会去的。但如果此问题已解决,请向上投票/勾选,以便其他人知道其已解决。同样,在引用min和eu_min表和matcode时,输入示例数据以帮助澄清您想要什么。