数据存储情况:
t_productbilldetails 1000万条数据。
t_productbilldetailvods 200万条数据。
t_adjustcharge 100条数据(没错,是100,不是100万!)
t_subscriberinfos 100万条数据。
视图情况:
其中 v_billdetail是由t_productbilldetails,t_productbilldetailvods这两个字段完全一样的表构成的视图。
create or replace view v_billdetail as
select
   detailbillid,
   subscriberid,
   productcode
from
   t_productbilldetails
union all
select
   detailbillid,
   subscriberid,
   productcode
from
   t_productbilldetailvods;
sql1:
select bd.productcode, si.deviceno
  from v_billdetail bd, t_adjustcharge adj, t_subscriberinfos si
 where bd.detailbillid = adj.detailbillid
   and bd.subscriberid = si.subscriberid;
执行sql1的时候,很慢。
执行计划如下:
---------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
| description |  Objectname       | Cost  | Io Cost | CPU Cost  |
----------------------------------------------------------------------------------------
select statement, goal = all_rows 18362 17896 2333357453
 hash join 18362 17896 2333357453
  index full scan dddddddddd 1 1 7321
  hash join 18319 17895 2122933371
   table access full t_subscriberinfos 3963 3915 240937592
   view v_billdetail 9138 8872 1331831075
    union-all
     partition range all 9136 8870 1331823953
      table access full t_productbilldetails 9136 8870 1331823953
     table access full t_productbilldetailvods 2 2 7121如果是将v_billdetail换成t_productbilldetails
也就是sq2:
select bd.productcode, si.deviceno
  from t_productbilldetails bd, t_adjustcharge adj, t_subscriberinfos si
 where bd.detailbillid = adj.detailbillid
   and bd.subscriberid = si.subscriberid
执行计划如下:
---------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
| description |  Objectname       | Cost  | Io Cost | CPU Cost  |
----------------------------------------------------------------------------------------
select statement, goal = choose 4 4 32696
 nested loops 4 4 32696
  nested loops 2 2 16343
   index full scan dddddddddd 1 1 7321
   table access by global index rowid t_productbilldetails 1 1 9021
    index unique scan pk_t_productbilldetails 1 1 9021
  table access by index rowid t_subscriberinfos 2 2 16353
   index unique scan pk_t_subscriberinfos 1 1 9021性能立即有了巨大的提高。
请问:
我该如何让sql1也能拥有和sql2一样的执行计划,速度也是一样的快?用hint可以吗?如果可以,具体该怎么写这个sql呢?
前提是sql1不要修改成
select bd.productcode, si.deviceno
  from t_productbilldetails bd, t_adjustcharge adj, t_subscriberinfos si
 where bd.detailbillid = adj.detailbillid
   and bd.subscriberid = si.subscriberid
union all
select bd.productcode, si.deviceno
  from t_productbilldetailvods bd, t_adjustcharge adj, t_subscriberinfos si
 where bd.detailbillid = adj.detailbillid
   and bd.subscriberid = si.subscriberid;

解决方案 »

  1.   

    select statement, goal = choose 4 4 32696
     nested loops 4 4 32696
      nested loops 2 2 16343
      index full scan dddddddddd 1 1 7321
      table access by global index rowid t_productbilldetails 1 1 9021
      index unique scan pk_t_productbilldetails 1 1 9021
      table access by index rowid t_subscriberinfos 2 2 16353
      index unique scan pk_t_subscriberinfos 1 1 9021由于索引的存在,sql2执行范围索引扫描,所以性能很好.v_billdetail 这个表中没有建立索引,所以是全表扫描.解决方案:在v_billdetail表中建立索引,billdetail表detailbillid 和 subscriberid 建立联合索引,再查看执行计划是否走索引.
      

  2.   

    谢谢两位建议。
    不过二位看清楚了,v_billdetail是个视图,不是表。在视图上建索引恐怕不太合适吧?
      

  3.   

    t_productbilldetailvods表上的连接列是不是也有索引?
      

  4.   

    to 楼上:
    是的,productbilldetailvods和productbilldetails两个表的所有字段、主键、索引都一样,只是表名和索引名字不一样而已。