通常我会选择最小的代码,但我目前正在构建一个支付网关,它可能每天处理数百万个连接,因此每次调整代码都可以帮助我建立性能,但是我有一个问题只能通过mysql gurus ..
使用union,最好用where子句过滤union的每一边,或者整理记录然后对union set进行过滤..
哪一个最快:
1)
select * from (
select * from payment_routes
where channel_id is null
and currency_id != v_currency_id
and card_id = v_card_id
and enabled = 1
union
select * from payment_routes
where channel_id = p_channel_id
and currency_id = v_currency_id
and card_id = v_card_id
and enabled = 1
) t1
join gateways g on t1.gateway_id = g.id
where t1.currency_id = v_currency_id
;
2)或者是这个较小的代码,快速/快速(但不慢)
select * from (
select * from payment_routes
where channel_id is null
and currency_id != v_currency_id
union
select * from payment_routes
where channel_id = p_channel_id
and currency_id = v_currency_id
) t1
join gateways g on t1.gateway_id = g.id
where t1.currency_id = v_currency_id
and t1.card_id = v_card_id
and t1.enabled = 1
;
从逻辑上讲,我会说(1)因为每个联合集都被过滤得更快,所以需要合并更少的记录。
我找到了一种更好的方法来编写没有联合的
select r.*, g.`name` 'gateway_name'
from payment_routes r
join gateways g on r.gateway_id = g.id
where (
(channel_id is null and currency_id != v_sell_currency_id)
or
(channel_id = p_channel_id and currency_id = v_sell_currency_id)
)
and card_id = v_card_id
and currency_id = v_pay_currency_id
and enabled = 1