您的位置:首页 > 数据库

DB2 NOT EXISTS 与NOT IN效率比较

2015-04-22 13:35 239 查看
最近在看牛新庄的《DB2数据库性能调整和优化》,他里面提及到NOT EXISTS与NOT IN的效率比较问题。 网上也看了不少讨论。按照书中结论EXISTS比IN 的效率高。网上也有相关的文章。也有无数网友推荐用EXISTS。但是我测试出来的结果是IN的效率比EXISTS高。

我们先来梳理EXISTS 与 IN的工作原理:

EXISTS是先得到外层表的结果集(例子中CUSTOMER中的结果),用外层表结果集一条一条在内层表中(TXNSALE)查询。

IN 是先生成内层表结果集(TXNSALE),再用外层表结果集到内层表去做比较。

书中的结论:外层结果集大,内层结果集小时,EXISTS效率高。外层结果集大,内层结果集小时,IN的效率高。

测试的结果:都是IN的效率高。

例子:

NOT IN 与 NOT EXISTS 的比较

查找出没有交易的客户和客户姓名,并统计他们的人数

CUSTOMER表中有6000000+条记录--小表

TXNSALE表中有40000000+条记录--大表

第一组比较:

外层表结果集数据小,内层表结果集大。按照书中的结论,外层循环是小结果集,内层循环大结果集,用EXISTS效率高。结果是采用IN的效率更高,EXISTS耗时18秒,IN耗时15秒。

NOT EXISTS:

[align=left]SELECT COUNT (*) FROM ([/align]
SELECT CUST_ID FROM CUSTOMER WHERE NOT EXISTS (SELECT 1 FROM TXNSALE WHERE CUST_ID
= TXNS_CUST_ID)
[align=left])AS TA[/align]
[align=left]结论:1360118条记录,耗费:18315ms[/align]
[align=left]
[/align]
[align=left]NOT IN:[/align]

[align=left]SELECT COUNT (*) FROM ([/align]
SELECT CUST_ID FROM CUSTOMER WHERE CUST_ID NOT IN (SELECT TXNS_CUST_ID FROM TXNSALE
)
[align=left]) AS TX[/align]
[align=left]结论:1360118条记录,耗费15803ms[/align]
[align=left]
[/align]
[align=left]第二组比较:[/align]
[align=left]我们缩减customer的范围(CUST_ID<10000时,其中有100条记录),把第一组的测试条件变的更苛刻:外层循环结果集小,内层循环结果集大。按照书中理论应该EXISTS效率高些,结果IN效率高。EXISTS耗时0.6秒,IN耗时0.09秒。[/align]

[align=left]SELECT COUNT (*) FROM ([/align]
SELECT CUST_ID FROM CUSTOMER WHERE CUST_ID < 10000 AND  NOT EXISTS (SELECT 1 FROM TXNSALE WHERE CUST_ID
= TXNS_CUST_ID)
[align=left])AS TA[/align]

[align=left]将customer的范围缩减到100条。[/align]
[align=left]429,686ms[/align]
[align=left]
[/align]

SELECT COUNT (*) FROM (
SELECT CUST_ID FROM CUSTOMER WHERE CUST_ID < 10000 AND CUST_ID NOT IN (SELECT TXNS_CUST_ID FROM TXNSALE
)
[align=left]) AS TX[/align]
[align=left]429,94ms[/align]

[align=left]
[/align]
[align=left]第三组比较:[/align]
[align=left]我们缩减customer的范围(TXNS_TRANS_NBR <10000时,其中有800+条记录):外层循环结果集大,内层循环结果集小。按照书中理论应该IN效率高些,结果IN效率高。EXISTS耗时10秒,IN耗时9秒。[/align]
[align=left]缩减in的范围(将TXNSALE范围缩小到800+条):[/align]

[align=left]SELECT COUNT (*) FROM ([/align]
SELECT CUST_ID FROM CUSTOMER WHERE NOT EXISTS (SELECT 1 FROM TXNSALE WHERE CUST_ID
= TXNS_CUST_ID AND TXNS_TRANS_NBR < 1000)
[align=left])AS TA[/align]
[align=left]6450321,10577ms[/align]

[align=left]SELECT COUNT (*) FROM ([/align]
SELECT CUST_ID,FROM CUSTOMER WHERE CUST_ID NOT IN (SELECT TXNS_CUST_ID FROM TXNSALE WHERE TXNS_TRANS_NBR
< 1000)
[align=left]) AS TX[/align]

[align=left]640321, 9765ms[/align]
[align=left]
[/align]
[align=left]结论:[/align]
[align=left]都是IN的效率比EXISTS高,无论外层内层结果集的大小如何。在DB2中,IN 的效率都比EXISTS高。不知道是不是现在商用数据库对半连接IN的优化。如果有新的结论。我会继续更新。[/align]
[align=left]这里仅仅是根据我测试的结果得出的结论,欢迎指正。[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  db2 数据库 IN EXISTS