3
通过与另一个表进行比较,查询将记录设置为不良。为了节省时间,我排除了已被标记为“不良”的记录。Oracle将'b'与'B'998x比较慢(10g或11g)的计划
我写了一个查询,但意外地检查了!='b'而不是!='B'...查询在0.203秒内执行。当我意识到自己的错误时,我将它改为!='B',但现在查询需要超过200秒才能执行!
当我检查计划时,'b'的优化器选择两个散列连接的串联。 'B'计划选择嵌套循环。
如果重要,我的测试中没有任何记录标记为'B'。 gsu.stg_userdata中有〜18,000条记录,gsu.userdata_compare中有〜73,000条记录。两个查询都得到相同(和正确)的结果数量。
查询:
select gstgu.global_id
from gsu.stg_userdata gstgu
left join gsu.userdata_compare guc
on (gstgu.global_id = guc.global_id) or (gstgu.user_id = guc.user_id)
where gstgu.row_check != 'b'
and ((-- Global IDs match, but two different Network IDs are explicitly set
(gstgu.global_id = guc.global_id) and (guc.user_id is not null and
gstgu.user_id is not null and
guc.user_id != gstgu.user_id))
-- Network IDs match, but two different Global IDs are explicitly set
or (guc.user_id = gstgu.user_id and (guc.global_id is not null and
gstgu.global_id is not null and
guc.global_id != gstgu.global_id))
or length(gstgu.global_id) != 8)
and guc.global_id != '00000000';
--
这个SQL计划:
Cost Card Bytes
SELECT STATEMENT, GOAL = ALL_ROWS 1014 1410 49350
CONCATENATION
HASH JOIN 507 559 19565
TABLE ACCESS FULL GSU STG_USERDATA 205 11144 189448
INDEX FAST FULL SCAN GSU USERCOMPARE_IDX 302 16979 305622
HASH JOIN 507 851 29785
INDEX FAST FULL SCAN GSU USERCOMPARE_IDX 302 16979 305622
TABLE ACCESS FULL GSU STG_USERDATA 205 17949 305133
如果我参加了完全相同的查询,并说
where gstgu.row_check != 'B'
花费超过200秒的执行(近1000倍,只要)和计划看起来像:
Cost Card Bytes
SELECT STATEMENT, GOAL = ALL_ROWS 507 1 35
NESTED LOOPS 507 1 35
TABLE ACCESS FULL GSU STG_USERDATA 205 1 17
INDEX FAST FULL SCAN GSU USERCOMPARE_IDX 302 1 18
我要疯了,怎么办?
。
有没有匹配'='b''的行?你对这一栏有什么样的统计数据吗? – Mat
没有任何行匹配'b',无论是...他们都是'N'。我不得不看看统计数据......他们现在只是开发中的表格,我们通常不会担心数据,直到表格出现为止。但我想不出为什么这么重要,因为既不是'b'也不是'B'。 –
“提及”B或b的陈旧直方图可能会产生奇怪的效果,例如您所看到的效果。 – Mat