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时,输入示例数据以帮助澄清您想要什么。