mysql null查询速度_为什么这个mysql查询(用null检查)是这么慢这个其他吗?

bd96500e110b49cbb3cd949968f18be7.png

I getting in doubt with "IS NULL" MySQL check. I have this 2 queries. The first one runs in about 300 seconds. The second one run less then 1 second!

Slow query:

SELECT count(distinct(u.id))

FROM ips_usuario AS u

JOIN ips_fatura AS f

ON ((u.id = f.ips_usuario_id) OR

(u.ips_usuario_id_titular IS NOT NULL AND

u.ips_usuario_id_titular = f.ips_usuario_id));

0jIct.jpg

Fast query:

SELECT count(distinct(u.id))

FROM ips_usuario AS u

JOIN ips_fatura AS f

ON ((u.id = f.ips_usuario_id) OR

(u.ips_usuario_id_titular = f.ips_usuario_id));

HxGOZ.jpg

All join conditions use foreign keys indexed columns. The table ips_usuario have about 20.000 records and the table ips_fatura have about 500.000 records.

解决方案

I am surprised that either is fast. I would suggest replacing them with exists:

SELECT COUNT(*)

FROM ips_usuario u

WHERE EXISTS (SELECT 1 FROM ips_fatura f WHERE u.id = f.ips_usuario_id) OR

EXISTS (SELECT 1 FROM ips_fatura f WHERE u.ips_usuario_id_titular = f.ips_usuario_id);

And for the second:

SELECT COUNT(*)

FROM ips_usuario u

WHERE EXISTS (SELECT 1 FROM ips_fatura f WHERE u.id = f.ips_usuario_id) OR

(u.ips_usuario_id_titular IS NOT NULL AND

EXISTS (SELECT 1 FROM ips_fatura f WHERE u.ips_usuario_id_titular = f.ips_usuario_id)

)

For both these, you want two indexes: ips_fatura(ips_usuario_id) and ips_fatura(ips_usuario_id_titular). You can check the explain to be sure that EXISTS is using the index. If not, the newer releases of MySQL use indexes for IN:

SELECT COUNT(*)

FROM ips_usuario u

WHERE u.id IN (SELECT f.ips_usuario_id FROM ips_fatura f) OR

u.ips_usuario_id_titular IN (SELECT f.ips_usuario_id FROM ips_fatura f);

In either case (EXISTS or IN) the goal is to do a "semi-join". That is, to only fine the first row with a match rather than all matches. This is an important efficiency, because it allows the query to avoid duplication removal.

I would speculate that the issue is the optimization of the or -- usually this results in inefficient JOIN algorithms. However, perhaps MySQL is smart in your first case. But the addition of the IS NULL to the outer table throws it off.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值