select HrEmployee.workId,HrEmployee.emplname,AtdRecord.recdate,AtdRecord.rectime,AtdRecord.equno,EquFinger.pws,rtrim(HrEmployee.workid)+','+AtdRecord.rectime as keyid from HrEmployee inner   join AtdRecord  on( HrEmployee.cardid=atdrecord.cardno)inner join EquFinger on(atdrecord.cardno=EquFinger.cardno) where rtrim(HrEmployee.workid)+','+AtdRecord.rectime  not in(select keyid from DCjilu)
这是,sql语句,作用是在3个表中查数据,有查两个字段的有查一个字段的会得到一个结果,然后将其中两个字段组合成一个新的字段,命名为keyid,然后以这个keyid作为主键和另外一个名字叫做DCjilu的表进行比较,如果前面的结果里面有后面这个表中没有的数据,就显示出来。我想问的有两点,
1.这个sql语句是不是太长了,这样用在数据库测试没有问题。是不是在程序中用,就没有问题。
2.如果理论上没有问题以后,那么,效率如何了,求高手指导,谢谢

解决方案 »

  1.   

    这懒的好歹排个版啊
    select HrEmployee.workId, HrEmployee.emplname, 
           AtdRecord.recdate, AtdRecord.rectime, AtdRecord.equno, 
           EquFinger.pws, 
           rtrim(HrEmployee.workid)+','+AtdRecord.rectime as keyid 
    from HrEmployee inner join AtdRecord on (HrEmployee.cardid=atdrecord.cardno)
         inner join EquFinger on (atdrecord.cardno=EquFinger.cardno) 
    where rtrim(HrEmployee.workid)+','+AtdRecord.rectime not in (select keyid from DCjilu)1.这个sql语句是不是太长了,这样用在数据库测试没有问题。是不是在程序中用,就没有问题。
    ——长不是问题,有问题也不是长本身的问题2.如果理论上没有问题以后,那么,效率如何了,求高手指导,谢谢
    ——效率烂得一屁,三表连接后,全表扫描
      

  2.   

    那就更慢了你的核心问题是查询条件是组合条件,没法预先建立索引,所以只能全表扫描。where rtrim(HrEmployee.workid)+','+AtdRecord.rectime not in
      

  3.   

    看这情况,分给少了。实际情况是,那个keyid不是必须的,那么做的原因是,三表连查到结果没有主键,但是两个字段组合,就是唯一的了,所以这个结果,插入下一个表,为了避免重复插入,我就用这个做了一个主键+not in可以排除重复插入这个,是不是,这样设计,很不合理啊。
      

  4.   

    分数不关键。根据你说的情况来看,确实设计上很不合理。数据规模越大,这个查询越容易害死人不过也看总规模了,如果总数据量在 1W 左右,关系不大;改造还比较的有点复杂度。
    看你这情况是想做增量更新之类的,如果在原始表上不加入 LAST_MODIFY 这类字段,处理起来总归是很麻烦,很难避免全表扫描。因为你关键所需过滤的字段分离在两个表,Oracle还不能跨表做组合索引。所以再怎么样,Oracle也只能老老实实的将这两个表做全连接,然后再双重循环做比对。