mysql exists,in, not exists ,not in效率疑问

meiyaxiong 2017-02-08 03:15:08
我在网上看到的都是一个观点
因为in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。在查询的两个表大小相当的情况下,EXISTS <= IN <= JOIN,NOT EXISTS <= NOT IN <= LEFT JOIN,如果两个表中一个较小,一个较大,则子查询表大的用exists,子查询表小的用in
但是我自己测试的时候却发现不是这样

已知
invoice_list表和invoice_package表数据均为为136万条,后表比前表多几千

select count(*) from invoice_package p where l.invoice=p.invoice and date< '2017-01-25' and date > '2017-01-18';
执行结果为1532条

SELECT l.invoice,l.uid,l.email,b.BFName FROM invoice_list l
LEFT JOIN invoice_package p ON p.invoice = l.invoice
LEFT JOIN invoice_bill_ship b ON b.invoice = l.invoice
WHERE p.date < '2017-01-25'
AND p.date > '2017-01-18'
AND l.channel IN ('','FR','CJ','WAP')
AND l.status NOT IN ('Cancelled','CustomerCancel','Emailed Product','');
执行结果1068 rows in set (2.12 sec)

SELECT l.invoice,l.uid,l.email,b.BFName FROM invoice_list l
LEFT JOIN invoice_bill_ship b ON b.invoice = l.invoice
WHERE exists (select invoice from invoice_package p where l.invoice=p.invoice and date< '2017-01-25' and date > '2017-01-18' )
AND l.channel IN ('','FR','CJ','WAP')
AND l.status NOT IN ('Cancelled','CustomerCancel','Emailed Product','');
执行结果1027 rows in set (30.28 sec)


SELECT l.invoice,l.uid,l.email,b.BFName FROM invoice_list l
LEFT JOIN invoice_bill_ship b ON b.invoice = l.invoice
WHERE l.invoice in (select invoice from invoice_package where date< '2017-01-25' and date > '2017-01-18' )
AND l.channel IN ('','FR','CJ','WAP')
AND l.status NOT IN ('Cancelled','CustomerCancel','Emailed Product','');
执行结果1027 rows in set (2.84 sec)

上面是left join,exists,in的比较


SELECT l.invoice,l.uid,l.email,b.BFName FROM invoice_list l
LEFT JOIN invoice_package p ON p.invoice = l.invoice
LEFT JOIN invoice_bill_ship b ON b.invoice = l.invoice
WHERE p.date < '2017-01-25'
AND p.date > '2017-01-18'
AND l.invoice NOT IN (SELECT invoice FROM blacklist)
AND l.channel IN ('','FR','CJ','WAP')
AND l.status NOT IN ('Cancelled','CustomerCancel','Emailed Product','');
执行结果1068 rows in set (1.85 sec)

SELECT l.invoice,l.uid,l.email,b.BFName FROM invoice_list l
LEFT JOIN invoice_package p ON p.invoice = l.invoice
LEFT JOIN invoice_bill_ship b ON b.invoice = l.invoice
WHERE p.date < '2017-01-25'
AND p.date > '2017-01-18'
AND not exists (SELECT invoice FROM blacklist b where l.invoice = b.invoice)
AND l.channel IN ('','FR','CJ','WAP')
AND l.status NOT IN ('Cancelled','CustomerCancel','Emailed Product','');
执行结果1068 rows in set (27.37 sec)

这个的left join不知道怎么写没测试
请问这是什么原因导致的
...全文
250 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
meiyaxiong001 2017-03-18
  • 打赏
  • 举报
回复
没人回答,关闭了

8,028

社区成员

发帖
与我相关
我的任务
社区描述
高性能数据库开发
社区管理员
  • 高性能数据库开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧