两个非常相似的选择语句不同的表现

时间:2016-02-28 10:09:12

标签: sql oracle performance

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

我有两个选择:

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)

大约需要20秒。

这一个:

{{1}}

大约需要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记录)

提前致谢。

1 个答案:

答案 0 :(得分:3)

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

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

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