有一个查询通过与另一个表比较来将记录设置为坏记录。为了节省时间,我排除了已经被标记为“坏”的记录。
我写了一个查询,但不小心检查了 != '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 秒(将近 1,000 倍),计划如下所示:
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
我要疯了,怎么了??
.
最佳答案
为 Row_check 字段添加一个索引....大多数时候这个问题都是由此引起的。
关于sql - Oracle 计划将 'b' 与 'B' 998x 比较慢(10g 或 11g),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8549911/