这很快:
select ba.name,
penamt.value penamt,
#address_line4.value address_line4
from account a
join customer c on a.customer_id = c.id
join branch br on a.branch_id = br.id
join bank ba on br.bank_id = ba.id
join account_address aa on aa.account_id = a.id
join address ad on aa.address_id = ad.id
join state s on ad.state_id = s.id
join import i on a.import_id = i.id
join import_bundle ib on i.import_bundle_id = ib.id
join (select * from unused where heading_label = 'PENAMT') penamt ON penamt.account_id = a.id
#join (select * from unused where heading_label = 'Address Line 4') address_line4 ON address_line4.account_id = a.id
where i.active=1
这很快:
select ba.name,
#penamt.value penamt,
address_line4.value address_line4
from account a
join customer c on a.customer_id = c.id
join branch br on a.branch_id = br.id
join bank ba on br.bank_id = ba.id
join account_address aa on aa.account_id = a.id
join address ad on aa.address_id = ad.id
join state s on ad.state_id = s.id
join import i on a.import_id = i.id
join import_bundle ib on i.import_bundle_id = ib.id
#join (select * from unused where heading_label = 'PENAMT') penamt ON penamt.account_id = a.id
join (select * from unused where heading_label = 'Address Line 4') address_line4 ON address_line4.account_id = a.id
where i.active=1
但这很慢:
select ba.name,
penamt.value penamt,
address_line4.value address_line4
from account a
join customer c on a.customer_id = c.id
join branch br on a.branch_id = br.id
join bank ba on br.bank_id = ba.id
join account_address aa on aa.account_id = a.id
join address ad on aa.address_id = ad.id
join state s on ad.state_id = s.id
join import i on a.import_id = i.id
join import_bundle ib on i.import_bundle_id = ib.id
join (select * from unused where heading_label = 'PENAMT') penamt ON penamt.account_id = a.id
join (select * from unused where heading_label = 'Address Line 4') address_line4 ON address_line4.account_id = a.id
where i.active=1
为什么我只包含两个子查询中的一个时速度很快但是当我包含两个子查询时速度很慢?我认为当我包括两者时它应该是两倍慢,但它需要很长时间。关于MySQL。
这是EXPLAIN
:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 19584
1 PRIMARY a eq_ref PRIMARY,fk_account_branch_id,fk_account_customer_id,fk_account_import_id PRIMARY 8 penamt.account_id 1
1 PRIMARY br eq_ref PRIMARY,fk_branch_bank_id PRIMARY 8 mcif.a.branch_id 1
1 PRIMARY i eq_ref PRIMARY,import_bundle_id PRIMARY 8 mcif.a.import_id 1 "Using where"
1 PRIMARY ba eq_ref PRIMARY PRIMARY 8 mcif.br.bank_id 1
1 PRIMARY c eq_ref PRIMARY PRIMARY 8 mcif.a.customer_id 1 "Using index"
1 PRIMARY ib eq_ref PRIMARY PRIMARY 8 mcif.i.import_bundle_id 1 "Using index"
1 PRIMARY aa ref fk_account_address_account_id,fk_account_address_address_id fk_account_address_account_id 8 mcif.a.id 1 "Using where"
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 368367 "Using where; Using join buffer"
1 PRIMARY ad eq_ref PRIMARY,fk_account_state_id PRIMARY 8 mcif.aa.address_id 1
1 PRIMARY s eq_ref PRIMARY PRIMARY 8 mcif.ad.state_id 1 "Using index"
3 DERIVED unused ref heading_label heading_label 257 469722 "Using where"
2 DERIVED unused ref heading_label heading_label 257 15632 "Using where"
答案 0 :(得分:1)
不回答您的确切问题,但如果您更改此类查询以完全摆脱子查询,我敢打赌它会明显更快:
select ba.name,
penamt.value penamt,
address_line4.value address_line4
from account a
join customer c on a.customer_id = c.id
join branch br on a.branch_id = br.id
join bank ba on br.bank_id = ba.id
join account_address aa on aa.account_id = a.id
join address ad on aa.address_id = ad.id
join state s on ad.state_id = s.id
join import i on a.import_id = i.id
join import_bundle ib on i.import_bundle_id = ib.id
left join unused penamt on penamt.account_id = a.id and penamt.heading_label = 'PENAMT'
left join unused address_line4 on address_line4.account_id = a.id and address_line4.heading_label = 'Address Line 4'
where i.active=1
答案 1 :(得分:0)
看来你正在寻找异常数据......那些缺少一些元素,其中你的最后两个查询是针对“未使用”的表,单独查找“heading_label”字段中的PEMAMT或地址行4。此外,除了custoemr帐户的银行分行之外,您不会获得其他信息。那么为什么要添加这些表,除非你的查询工作后你会得到其他数据......那就是说,我会预先查询你的“特殊”标准,然后加入帐户表。使用顶部的“STRAIGHT_JOIN”子句告诉系统按列出的顺序执行此操作。因此,应首先执行预查询,并仅限定那些需要审阅/缺失数据的帐户。然后,在预先查询期间,如果我按最大值分组...并在该查询中获取PENAMT和ADDRESS_LINE_4,我不需要在以后的连接中再次执行它...一切都在前面。
这是我的查询。
select STRAIGHT_JOIN
ba.name,
PreQuery.penamt,
PreQuery.address_line4
from
( SELECT account_id,
MAX( CASE WHEN heading_label = 'PENAMT'
THEN heading_label END ) penamt,
MAX( CASE WHEN heading_label = 'Address Line 4'
THEN heading_label END ) Address_line4
from
unused
where heading_label = 'PENAMT'
OR heading_label = 'Address Line 4'
group by
unused.account_id ) PreQuery
join account a
ON PreQuery.account_id = a.id
join customer c
on a.customer_id = c.id
join branch br
on a.branch_id = br.id
join bank ba
on br.bank_id = ba.id
join account_address aa
on a.id = aa.account_id
join address ad
on aa.address_id = ad.id
join state s
on ad.state_id = s.id
join import i
on a.import_id = i.id
join import_bundle ib
on i.import_bundle_id = ib.id
where
i.active = 1