1 不一定sql越长反倒性能越差,尽量多where条件使得初始结果集最小,然后再和其他表相连

2 使用patition

3 同一个结果集被多次使用,可以使用with table

4 谓词推进

--分页 第一种写法会有stopkey
(1)
select y.*
  from (select z.*, rownum as startRow
          from (
               select * from tbaa where customerno='asdf' order by accessdate desc
          ) z
                  where rownum <= 20
        ) y
 where y.startRow > 2
 
(2) 
 select z.*
   from (select * from tbaa where customerno = 'asdf' order by accessdate desc) z
  where rownum <= 20
    and rownum > 1 
  select z.*
   from (select * from tbaa where customerno = 'asdf' order by accessdate desc) z
  where rownum between 0 and 20
 
 
   --我想要指出我在这个例子中使用了一技巧阻止谓词推进。在第二个查询中使用rownum伪列(我加谓词WHERE rownum > 1)用于禁止谓词推进。
事实上,rownum不仅禁止谓词推进也禁止视图合并。 使用rownum就好像在查询中加了NO_MERGE和NO_PUSH_PRED 提示。在本例中,
它让我指出谓词推进没有发生时的负面效果,我还想确保你知道:当确定执行计划时,使用rownum将影响优化器的有效选择。
当你使用rownum时要小心--它将使得它所在的任何查询块变得非可合并且不能把谓词推进入其中。
 
5 left join加where条件的不同情况
--channel是cardMemory的才会和右表连接
with ta as
 (select customerno, channel, pv
    from tbaa
   where accessdate = '2017-06-20'
     and customerno = 'dd'),
tb as
 (select customerid, machineid
    from tbbb
   where stat_date = '2017-06-20'
     and customerid = 'dd')
select ta.customerno, ta.channel, ta.pv, tb.machineid
  from ta
  left join tb
    on ta.customerno = tb.customerid
   and ta.channel = 'cardMemory'
 
with ta as
 (select customerno, channel, pv
    from tbaa
   where accessdate = '2017-06-20'
     and customerno = 'dd'),
tb as
 (select customerid, machineid
    from tbbb
   where stat_date = '2017-06-20'
     and customerid = 'dd')
select ta.customerno, ta.channel, ta.pv, tb.machineid
  from ta, tb
 where ta.customerno = case
         when ta.channel = 'cardMemory' then
          tb.customerid(+)
         else
          null
       end