|
|
原帖由 rollingpig 于 2008-3-17 13:24 发表 ![]()
这样如何?
select /*+ leading(b) use_hash(a b) */ distinct a.ID
from BIG_TABLE a, SMALL_TABLE b
where (a.category||' '||a.site_id = b.from_cat||' '||b.site_id
or a.category2||' '||a.site_id = b.from_cat||' '||b.site_id
) and a.sale_end >= sysdate;
这是你的SQL的PLAN,个人感觉上没有用Union自然
[PHP]
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 81 | 7047 | 34 (12)|
| 1 | SORT UNIQUE | | 81 | 7047 | 34 (12)|
| 2 | CONCATENATION | | | | |
|* 3 | HASH JOIN | | 4 | 348 | 17 (12)|
| 4 | TABLE ACCESS FULL| SMALL_TABLE | 1879 | 48854 | 14 (8)|
|* 5 | TABLE ACCESS FULL| BIG_TABLE | 4 | 244 | 3 (34)|
|* 6 | HASH JOIN | | 4 | 348 | 17 (12)|
| 7 | TABLE ACCESS FULL| SMALL_TABLE | 1879 | 48854 | 14 (8)|
|* 8 | TABLE ACCESS FULL| BIG_TABLE | 4 | 244 | 3 (34)|
--------------------------------------------------------------------------
[/PHP]
我们在tuning sql的时候可以站在oracle的角度想问题
起初我认为oracle应该更加smart一点,可以通过small_table(from_cat,site_id)来建立build table,然后在probe big_table的时候计算出两个hash值,第一个值基于(category, site_id),第二个值基于(category2,site_id)然后根据这两个hash值选择相应的bucket做链表扫描,这样的话FTS只需要一次
可惜oracle让我失望了,并没有如我一般的smart ,所以两次FTS无法避免 |
|