分析某段时间内,刷卡金额大于1000的卡的消费记录,写法如下。
sql语句写法:select a.dno,a.dcard,a.dcard_money,a.dcard_type,a.ddate,
a.dsubshop,a.dworker,a.dtype,j.Djf DNowjf,b.dsje,B.Dcountfrom st_card_salemx a,
( select m.dcard,Count(1) Dcount,Sum(dcard_money) dsje
from st_Card_Salemx m
where ddate >= to_Date('2016-7-17','yyyy-mm-dd')
and Ddate <= to_Date('2016-7-19','yyyy-mm-dd')
and dcard_type <> '06'
group by m.dcard
having Sum(dcard_money) >= 1000 ) b,st_card_jf j
where a.dcard = b.dcard and b.dcard = j.dcardno
and a.ddate >= to_Date('2016-7-17','yyyy-mm-dd')
and a.Ddate <= to_Date('2016-7-19','yyyy-mm-dd')
order by 2
问题:刚开始使用的时候,3分钟可以出结果,用了一年以后,40分钟都还没有出结果。Dcard是主键,Ddate有索引,原因不明。有谁知道原因的请回复,十分感谢。
我的解决办法:1、对子查询b生成临时表,用的时候往临时表中写入数据,查询完成即删除。
创建临时表Create Global Temporary Table b(dcard varchar(20),dcount int,dsje numeric(12,2) )On Commit Preserve Rows;
2、这样上面的查询语句改为
select a.dno,
b,'yyyy-mm-dd')
order by 2
3、查询。在程序中先启动事务,往b表中写入数据(就是子查询的内容),执行查询,回滚事务。这样数据就能正确的显示,并且速度很快,效率很高。
虽然问题得到了解决,但是原因未查明,请求指点。
备注:临时表比较
sqlserver:分本地临时表仅在当前会话中可见;全局临时表在所有会话中都可见。本地临时表的名称前面有一个编号符 (#table_name),而全局临时表的名称前面有两个编号符 (##table_name)。表结构是临时的,会话结束或者重启服务之后,临时表即消失。
Oracle:表结构是永久的,重启服务也依然存在,除非显式drop table。