- 1、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
exists的过滤条件位置导致性能相差几个数量级
昨天测试housekeepr的一句语句执行了一整晚上到今天都没有结束:
insert /*+ append parallel(det 4) */
into olp_housekeep_property_detail det
(table_oid,
rec_rowid,
primary_key_value,
keyword_value,
table_name,
pkcondition)
select /*+ parallel(sds 4) */
2367, sds.rowid, sds.SHPDOC_SUPP_OID, null, LLP_SHPDOC_SUPP, null
from LLP_SHPDOC_SUPP sds
where exists (select 1
from LLP_SHPDOC sd, olp_housekeep_property_detail ohpd
where sd.shpdoc_num = sds.shpdoc_num
and sd.shpdoc_three_pl_code = sds.shpdoc_threepl
and ohpd.table_name = LLP_SHPDOC
and ohpd.rec_rowid = sd.rowid);
我们去掉分批hints,只拿出查询部分,看下执行计划:
发现Oracle又因为没有统计信息乐观地认为只需要很短时间,无视之。不过我们赫然发现了第7步的对LLP_SHDOC_SHUPP表,即exists外表的的全表扫描,为什么?因为对其所有的过滤条件都没有,100%是要走全表扫描的,虽然下面有exists的过滤,但不在最外面的一层有自己的过滤条件,需要对其全表每扫描一次(这个表有99W条纪录,即要循环99W次),再与exists里的条件,即外表加里面的2个表再进行关联查询,是非常恐怖的,直接导致这个看似非常简单的查询一晚上都跑不完,我们将exists改为关联查询:
我们发现立刻去掉了全面扫描,快多了,但发现第4步仍然是使用了filter,而不是access,实际查询的结果仍然很慢。我们知道,通过rowid对表的访问是最快的(当然了,索引就是依此而建的),但这里应该是一个unique的access,为什么会变成filter?看了下统计信息,果然是非常的陈旧了,然后对3张表进行了统计信息收集,另加入了对表列的收集:
analyze table LLP_SHPDOC_SUPP compute statistics for table for all indexes for all indexed columns;
analyze table LLP_SHPDOC compute statistics for table for all indexes for all indexed columns;
analyze table olp_housekeep_property_detail compute statistics for table for all indexes for all indexed columns;
当然,原表统计信息要备份,做完housekeep发现性能降低,可回退。再看下结果,oracle全部使用了access,当然就是瞬间的事情了,不知道差了多少的数量级:
由于我们知道,Exists不是万能的,效率一定是不如关联查询的,能用关联查询的一定要用关联查询,因为最有可能有索引。如果使用exists,则对目标表的过滤条件一定要放在exists查询之外。
我们再来看几个例子(非我们的库,只做例子):
UPDATE syj_sx_060314.wa_data
SET ts = 2006-04-14 08:45:42,
f_42 = COALESCE(ROUND(wa_data.f_143, 2), 0)
WHERE EXISTS (SELECT null
FROM syj_sx_060314.bd_accpsndoc
WHERE bd_accpsndoc.pk_psndoc = wa_data.psnid
AND wa_data.classid = 1015AA10000000019Z7P
AND wa_data.cyear = 2006
AND wa_data.cperiod = 04
AND wa_data.dr =
文档评论(0)