源sql:
SELECT A.ROW_ID,
       A.SERVICE_INFO_ID,
       A.USER_ID,
       C.DESCC,
       B.DESCC AS PRODTYPE,
       A.FM_INFO_SERIALNO,
       A.REPLACE_CAUSE,
       DECODE(K.PRODUCT_CODE || '*' || G.FAULT_CODE,
              '*',
              '',
              K.DESCC || '*' || G.FAULT_CODE) AS CO_FAULT_CAUSE,
       F.NETNAME,
       D.CHECK_TIME,
       H.BRANCH_NAME,
       A.ACCEP_STATUS,
       A.RECEIVE_TIME,
       A.RETURN_STATUS
  FROM CD_FAULT_DESC       G,
       CD_PRODOBJ          K,
       CD_PRODUCT          C,
       CD_PRODTYPE         B,
       CD_SERVICE_NET_INFO F,
       CD_BRANCH           H,
       WO_FEEDBACK         E,
       WO_REBACK           D,
       WO_FM_REGISTER      A
 WHERE A.ACTIVE_FLAG = '1' AND D.ACTIVE_FLAG = '1' AND B.ACTIVE_FLAG = '1' AND
       C.ACTIVE_FLAG = '1' AND F.ACTIVE_FLAG = '1' AND
       A.PRODUCT_ID = C.ROW_ID AND B.ROW_ID = A.PRODTYPE_ID AND
       F.ROW_ID = A.REPLACE_SERVICE_ID AND H.ROW_ID = A.BRANCH_ID AND
       G.ROW_ID = E.FAULT_DESC_ID AND K.ROW_ID = E.PRODOBJ_ID AND
       E.SERVICE_INFO_ID = A.ROW_ID AND D.FM_REGISTER_ID = A.ROW_ID AND
       A.PRODUCT_ID IN ('19') AND A.ACCEP_STATUS = 'c' AND
       D.CHECK_TIME >= TO_DATE('2004-04-01 00:00', 'YYYY-MM-DD HH24:mi ') AND
       D.CHECK_TIME < TO_DATE('2004-04-03 23:59', 'YYYY-MM-DD HH24:mi');
       主要现象为select count(*)有数据, select * 没有数据, 如果把where条件中A.PRODUCT_ID IN ('19')换成A.PRODUCT_ID IN ('19', '-1')数据就出来了.
       A.PRODUCT_ID 没有为-1的记录.
       如果哪位大虾知道这个现象是怎么回事, 请指教.http://expert.csdn.net/Expert/topic/2921/2921639.xml?temp=.7533838这以前发的帖子, 没有解决问题, 今天数据库又发生的类似的问题, 不得不再次发贴. 且这样的问题是同样的sql突然某天就查不到数据了!  郁闷得一塌糊涂啊!!!!

解决方案 »

  1.   

    你看看有数据和无数据的执行计划是否相同
    我估计不同,你这几个表的join关系很复杂,可能某个access path中先过滤掉了你后续join需要的数据。select count(*) 和 select * 的执行计划应该不同A.PRODUCT_ID IN ('19')因为只有一个值,优化器可能会优化成inner join(a.product_id='19')
      

  2.   

    A.PRODUCT_ID IN ('19') 这可以换成 A.PRODUCT_ID='19'
    可能表A中的PRODUCT_ID没有'19'这个值select distinct product_id from WO_FM_REGISTER, 看看都有哪些值?
      

  3.   

    谢谢大家的个关注
    to drabit(square):
       你说的是正确的, 当in里面的数据只有一个时, 会把in转化成=. 执行计划的确不同, 但还是看不出是哪里出的问题;
       
      

  4.   

    SELECT STATEMENT, GOAL = FIRST_ROWS 17 2714 2705858
     FILTER
      NESTED LOOPS 17 2714 2705858
       NESTED LOOPS 12 5 4675
        NESTED LOOPS 11 1 813
         NESTED LOOPS 10 1 793
          NESTED LOOPS 8 1 770
           NESTED LOOPS 7 1 732
            NESTED LOOPS 5 2 1334
             NESTED LOOPS 3 2 1078
              TABLE ACCESS BY INDEX ROWID HCSP T_PRODUCT 1 1 515
               INDEX UNIQUE SCAN HCSP PK_T_PRODUCT 82
              TABLE ACCESS BY INDEX ROWID HCSP WO_REBACK 2 2 48
               INDEX RANGE SCAN HCSP WO_REBACK_N1 1 4
             TABLE ACCESS BY INDEX ROWID HCSP WO_FM_REGISTER 1 1 128
              INDEX UNIQUE SCAN HCSP PK_WO_FM_REGISTER 440
            TABLE ACCESS BY INDEX ROWID HCSP CD_SERVICE_NET_INFO 1 1 65
             INDEX UNIQUE SCAN HCSP PK_CD_SERVICE_NET_INFO 100
           TABLE ACCESS BY INDEX ROWID HCSP T_PRODTYPE 1 1 38
            INDEX UNIQUE SCAN HCSP PK_T_PRODTYPE 2
          TABLE ACCESS BY INDEX ROWID HCSP WO_FEEDBACK 2 1 23
           INDEX UNIQUE SCAN HCSP WO_FEEDBACK_WO_ID 1 23
         TABLE ACCESS BY INDEX ROWID HCSP T_FAULT_DESC 1 1 20
          INDEX UNIQUE SCAN HCSP PK_T_FAULT_DESC 1
        TABLE ACCESS BY INDEX ROWID HCSP T_PRODOBJ 1 17 2074
         INDEX UNIQUE SCAN HCSP P_INDEX_PREOBJ 1
       TABLE ACCESS BY INDEX ROWID HCSP CD_BRANCH 1 582 36084
        INDEX UNIQUE SCAN HCSP PK_CD_BRANCH 1
    这个是in('19')时的执行.
      

  5.   

    SELECT STATEMENT, GOAL = FIRST_ROWS 14 1 997
     FILTER
      NESTED LOOPS 14 1 997
       NESTED LOOPS 13 1 935
        NESTED LOOPS 12 1 813
         NESTED LOOPS 11 1 793
          NESTED LOOPS 9 1 770
           NESTED LOOPS 8 1 732
            NESTED LOOPS 7 1 667
             NESTED LOOPS 5 2 304
              TABLE ACCESS BY INDEX ROWID HCSP WO_REBACK 3 2 48
               INDEX RANGE SCAN HCSP WO_REBACK_N1 2 4
              TABLE ACCESS BY INDEX ROWID HCSP WO_FM_REGISTER 1 1 128
               INDEX UNIQUE SCAN HCSP PK_WO_FM_REGISTER 214
             INLIST ITERATOR
              TABLE ACCESS BY INDEX ROWID HCSP T_PRODUCT 1 1 515
               INDEX UNIQUE SCAN HCSP PK_T_PRODUCT 1
            TABLE ACCESS BY INDEX ROWID HCSP CD_SERVICE_NET_INFO 1 1 65
             INDEX UNIQUE SCAN HCSP PK_CD_SERVICE_NET_INFO 100
           TABLE ACCESS BY INDEX ROWID HCSP T_PRODTYPE 1 1 38
            INDEX UNIQUE SCAN HCSP PK_T_PRODTYPE 2
          TABLE ACCESS BY INDEX ROWID HCSP WO_FEEDBACK 2 1 23
           INDEX UNIQUE SCAN HCSP WO_FEEDBACK_WO_ID 1 23
         TABLE ACCESS BY INDEX ROWID HCSP T_FAULT_DESC 1 1 20
          INDEX UNIQUE SCAN HCSP PK_T_FAULT_DESC 1
        TABLE ACCESS BY INDEX ROWID HCSP T_PRODOBJ 1 17 2074
         INDEX UNIQUE SCAN HCSP P_INDEX_PREOBJ 1
       TABLE ACCESS BY INDEX ROWID HCSP CD_BRANCH 1 582 36084
        INDEX UNIQUE SCAN HCSP PK_CD_BRANCH 1
    这个是in('19', '-1')时的执行
      

  6.   

    看看A.PRODUCT_ID的字段属性,是否为number或数字类型,如果是的话,先把'19'上的引号去掉试一下看看,我不知道你为什么要用in,可以直接改成A.PRODUCT_ID=19
    理论上说,select count(*) 有的话,select *  就会有数据.
      

  7.   

    从执行计划看
    1.in('19')的时候,     最先做的是WO_REBACK 和 CD_PRODUCT 的nested loop
    2.in('19','-1')的时候,最先做的是WO_REBACK 和 WO_FM_REGISTER 的nested loop 1的结果集记录数少于WO_REBACK 的记录数,再去跟WO_FM_REGISTER做nested loop时便产生了问题。你可以调整一下where条件里面表的join顺序,确保WO_REBACK 和WO_FM_REGISTER 的loop先做 
      

  8.   

    A.PRODUCT_ID IN ('19') ,这样写没有任何好处,你先把这条语句去掉,试试看,然后换成=号试试看
    还有就是调优问题,你把你的条件再调调顺序,这个是有关系的,比方如下说:select value from table where 
    isnull(value,0) > 0 and 1/isnull(value,0) > -100and 两边的条件,你调个顺序后,结果不一样;试试看再说尤其是:select count(*)有数据, select * 没有数据,很可能跟这个有关系
      

  9.   

    应该不会出现这种问题才是,你先把表关联的条件写在前面试试看.
    select * from t1,t2,t3
      where t1.col1 = t2.col2 -- 必要时加个 (+)
        and t2.col2 = t3.col3
        and t1.col1 = '1'
        and ...