我刚刚遇到了一些奇怪的性能差异。
我有两个选择:
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)
什么可能导致这种奇怪的行为?..
FCT表索引为UNIQUE(dwh_product_key,dwh_end_date)并由dwh_end_date(2.5亿条记录)分区,STG没有任何索引(及其仅有15k记录)
提前致谢。
答案 0 :(得分:3)
计划不完全相同。第一个查询使用fct_customer_services
上的索引的快速完整扫描,并且不需要访问实际表中的任何块,因为您只引用了两个索引列。
第二个查询必须访问表块以获取其他未定义的列值。它正在进行全表扫描 - 比全索引扫描更慢,更昂贵。优化器没有看到使用索引然后访问特定表行的任何改进,可能是因为基数太高 - 它需要访问太多表行以通过首先命中索引来节省任何工作量。这样做会更慢。
所以第二个查询速度较慢,因为它必须从磁盘/缓存而不是整个索引读取整个表,并且表比索引大得多。您可以查看分配给两个对象(索引和表)的段,以查看其大小的比率。