【问题标题】:Oracle plan for comparing 'b' vs. 'B' 998x as slow (10g or 11g)Oracle 计划将 'b' 与 'B' 998x 比较慢(10g 或 11g)
【发布时间】:2012-01-22 21:49:14
【问题描述】:

有一个查询,通过与另一个表进行比较来将记录设置为坏记录。为了节省时间,我排除了已经标记为“不良”的记录。

我写了一个查询,但不小心检查了 != '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


我快疯了,是什么原因??

.

【问题讨论】:

  • 有没有匹配= 'b'的行?您对该列有任何统计信息吗?
  • 没有一行匹配'b',要么......它们都是'N'。我将不得不查看统计信息...它们现在只是 dev 中的表格,我们通常不会担心统计信息,直到表格在 prod 中。但考虑到“b”和“B”都没有出现在表格中,我想不出有什么重要的原因。
  • “提及”Bb 的陈旧直方图可能会产生与您所看到的一样的奇怪效果。
  • 能否给出涉及表的列?
  • 最好的办法是使用跟踪来准确验证优化器在做什么 - 将节省您猜测可能发生的事情的时间 - 问题:值 'b' 曾经存在于列中的某个时间点?

标签: sql oracle oracle11g sql-execution-plan


【解决方案1】:

为 Row_check 字段添加索引 .... 大多数情况下,此问题是由此引起的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 2015-12-02
    • 2015-06-13
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多