【问题标题】:Two very alike select statements different performance两个非常相似的select语句不同的表现
【发布时间】:2016-02-28 10:09:11
【问题描述】:

我刚刚遇到了一些奇怪的性能差异。

我有两个选择:

SELECT s.dwh_end_date,
       t.*,
       '-1' as PROMOTION_DROP_EMP_CODE,
       trunc(sysdate +1) as PROMOTION_END_DATE,
      'K01' as PROMOTION_DROP_REASON,
       -1 as PROMOTION_DROP_WO_NUMBER
FROM STG_PROMO_EXPIRE_DATE t
INNER JOIN fct_customer_services s
 ON(t.dwh_product_key = s.dwh_product_key)

这大约需要 20 秒。

还有这个:

SELECT s.dwh_end_date,
       s.dwh_product_key,
       s.promotion_expire_date,
       s.PROMOTION_DROP_EMP_CODE,
       s.PROMOTION_END_DATE,
       s.PROMOTION_DROP_REASON,
       s.PROMOTION_DROP_WO_NUMBER
FROM STG_PROMO_EXPIRE_DATE t
INNER JOIN fct_customer_services s
 ON(t.dwh_product_key = s.dwh_product_key)

这大约需要 400 秒

它们基本上是相同的——只是为了确保我已经正确更新了我的数据(第一个选择是更新 FCT 表)第二个选择是为了确保每件事都正确更新。

这两个选择之间的唯一区别是我选择的列。 (STG 表有两列——dwh_p_key 和 prom_expire_date)

First select explain plan

Second select explain plan

什么会导致这种奇怪的行为?..

FCT 表索引为 UNIQUE (dwh_product_key, dwh_end_date) 并按 dwh_end_date 分区(2.5 亿条记录),STG 没有任何索引(只有 15k 条记录)

提前致谢。

【问题讨论】:

  • 请粘贴说明图,没有图片
  • 这些时间是返回所有行还是只返回结果的第一页?如果您重复运行这两个查询,它们是否一致,或者您可能只是看到块缓存的效果?并且计划相同,请再次查看底部两行作为开始,以及字节值。索引全扫描与全表扫描是一个显着的区别。
  • @AlexPoole 你是对的,我没有注意到它。是的,它们反复出现,无论我运行它们多少次,这些都是结果。为什么会发生这种巨大的差异?
  • 执行计划的纯文本显示比图像好得多。计划的文本版本包含比图像更有用的信息。所以在未来,请将执行计划添加为(格式化的)文本,而不是图像(绝对不是你的完整 SQL 客户端的图像)

标签: sql oracle performance


【解决方案1】:

计划完全相同。第一个查询对fct_customer_services 上的索引进行快速全扫描,不需要访问实际表中的任何块,因为您只引用了两个索引列。

第二个查询必须访问表块才能获取其他未索引的列值。它正在执行全表扫描 - 比全索引扫描更慢且更昂贵。优化器没有看到使用索引然后访问特定表行的任何改进,可能是因为基数太高 - 它需要访问太多表行以通过首先点击索引来节省任何努力。这样做会更慢。

所以第二个查询比较慢,因为它必须从磁盘/缓存中读取整个表,而不仅仅是整个索引,而且表比索引大得多。您可以查看分配给两个对象(索引和表格)的段以查看它们的大小比例。

【讨论】:

  • 但是如果查询已经访问了表并获得了 dwh_product_key ,为什么从同一行中选择另一列时需要对表进行不同的访问?
  • @Yossi - 在第一个查询中,它只需要查看索引即可获取 dwh_product_key(用于连接)和 dwh_end_date(用于选择列表)。其他表列不需要其他任何内容。在第二个查询中,promotion_expire_date not 在该索引中,它仅在实际表中。它不会两次访问该表,而是进行一次全表扫描以获取 dwh_product_key 丢失选择所需的所有其他列值。
  • 太好了,谢谢。 @AlexPoole
猜你喜欢
  • 1970-01-01
  • 2018-01-25
  • 2022-07-01
  • 2021-10-25
  • 1970-01-01
  • 1970-01-01
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多