数据库查询,速度奇慢!(100分)

  • 主题发起人 主题发起人 jlyin
  • 开始时间 开始时间
J

jlyin

Unregistered / Unconfirmed
GUEST, unregistred user!
select RM.User_no,RM.User_Name,RM.address,
I.MeterNo,I.BranchNo,I.NowPay,I.Ullage_Amt,I.Paydate
from Rmeter_params RM,Issuecard I
where I.MeterNo=RM.MeterNo
and I.Flag<2
and I.PayDate<:fromdate
and I.paydate=(select max(paydate) from Issuecard IC where IC.meterno=RM.meterno)

{上面的查询速度太慢,无论是用PARDOX,ORALCE,
请教高手,如何优化,要重新设计吗?

只要数据量大,有时要半小时都不出,
关键是在售电库RM,Issuecard库查出有记录,但最近X天又没有记录的所有记录;
与最后一个AND语句有关,换成 EXIST或IN也不行}







 
有多少记录啊,你这样的查询能快才怪呢,尽量不要用<或>这样会影响速度
 
先用
select max(paydate) from Issuecard IC where IC.meterno=RM.meterno
查询出结果,再用
select RM.User_no,RM.User_Name,RM.address,
I.MeterNo,I.BranchNo,I.NowPay,I.Ullage_Amt,I.Paydate
from Rmeter_params RM,Issuecard I
where I.MeterNo=RM.MeterNo
and I.Flag<2
and I.PayDate<:fromdate
and I.paydate=结果
看看效率如何
 
有其他方法代替吗?

我只想知道:
IC卡售电系统,已开户,但最近(比如三个月内)又不来购电的用户查出来(最后购电日期)
和打印
 
TO YSAI
你的方法不行,第一个查询就有很多记录,除非存到一个表中,
否则没法=结果,本来IC。MATERNO就很多,
每次只查一个表号,没有用处
 
select RM.User_no,RM.User_Name,RM.address,
I.MeterNo,I.BranchNo,I.NowPay,I.Ullage_Amt,I.Paydate
from Rmeter_params RM,Issuecard I
where I.MeterNo=RM.MeterNo and i.meterno in (
select meterno from (
select MeterNo,max(paydate)
from Issuecard
where Flag<2 and PayDate<:fromdate
group by MeterNo
)
)
 
TO YSAI
上面的查询意义变了,不符合要求;
你的最大日期,是所有记录的最大,而不是本电表的最后购电记录;
 
SORRY,
没注意有GROUPBY,我试试;
 
select RM.User_no,RM.User_Name,RM.address,
I.MeterNo,I.BranchNo,I.NowPay,I.Ullage_Amt,max(I.Paydate)
from Rmeter_params RM,Issuecard I
where I.MeterNo=RM.MeterNo
and I.Flag<2
group by RM.User_no,RM.User_Name,RM.address,
I.MeterNo,I.BranchNo,I.NowPay,I.Ullage_Amt
having datediff(day,max(i.paydate),getdate())>:n
// having max(i.paydate)<:rq
// parambyname('rq').asdatetime:=date-//多少天无记录
parambyname('n').asinteger:=30
 
不用试了;
一分析就知,你的查询还是不符合我的要求;
主要是GROUPBY,包含了日期限制,并不表示此表三个月没有记录;
而只能保证查出三个月以前开户(有第一次购电)的最接近于三个月的当天记录;
换成,max(paydate)<:fromdate,语句有错吗?
 
select RM.User_no,RM.User_Name,RM.address,
I.MeterNo,I.BranchNo,I.NowPay,I.Ullage_Amt,I.Paydate
from Rmeter_params RM,Issuecard I
where I.MeterNo=RM.MeterNo and i.meterno in (
select meterno from (
select MeterNo,max(paydate) as paydate
from Issuecard
where Flag<2
group by MeterNo
) where PayDate<:fromdate
)
 
实在是不好意思,我也做过售电系统
 
SORRY

datediff()函数是通用,还是专用?
对ORACLE或PARADOX都好用吗?
 
最主要的是不要让
select max(paydate) from Issuecard IC where IC.meterno=RM.meterno
这句sql执行太多次,可以这样写:
select RM.User_no,RM.User_Name,RM.address,
I.MeterNo,I.BranchNo,I.NowPay,I.Ullage_Amt,I.Paydate
from Rmeter_params RM,Issuecard I,
(select distinct meterno max(paydate) maxdate from Issuecard) TMP
where I.MeterNo=RM.MeterNo
and I.Flag<2
and I.PayDate<:fromdate
and I.meterno = TMP.meterno
and I.paydate = TMP.maxdate
但有的数据库可能不支持这种写法。
第二,对Rmeter_params,Issuecard 两表的meterno字段和Issuecard表的paydate字段建立索引,
即使使用你的SQL语句,也会明显提高查询效率,你可以试试。
 
我试试,多谢三位答复,

关于索引:
两个库都有主索引,
如ISSUCEARD:
METERNO+BRANCHNO+PAYDATE+PATIME
意为:表号+表计号+日期+时间,
只因表计号在多用户表才用得上,故多用缺省值,就不考虑了,购电时间,一天不会两次就极少用;
还要另外为表号之类另建索引吗?

其二,用<号慢一些吗,
将I.flag<2换成I.flag in [0,1]会快吗?
 
建议对paydate字段单独建立群集索引,因为该字段可能有大量重复值,且要使用范围查询(如<)。
 
另外,将I.flag<2换成I.flag in [0,1]可能会更慢,
因为语法分析器会将其转化为I.flag = 0 or I.flag = 1来执行,相当于对每列扫描两次,或者更糟。
 
select RM.User_no,RM.User_Name,RM.address,
I.MeterNo,I.BranchNo,Max(I.Paydate) as PAYDATE
from Rmeter_params RM,Issuecard I
where I.MeterNo=RM.MeterNo
and I.Flag<2
Group By RM.User_no,RM.User_Name,RM.address,
I.MeterNo,I.BranchNo,
HAVing PAYDATE<:fromdate
{先这样吧,数据库不在这里,没法调
不能满意的是,两个字段购电金额和变损金额I.NowPay,I.Ullage_Amt不能查出了
快了但用户不一定认可:)
BTW 三层SELECT 不慢吗?还是只与语句有关?}
 
这个SQL语句是不行的,在使用了聚合函数Max后,
RM.User_no,RM.User_Name,RM.address,I.MeterNo,I.BranchNo
所形成的任意一个组合都有其自己的Max(I.Paydate),
那么这个Max(I.Paydate)是你所期望的吗?!
 
没有问题,
这些只是与电表相关的用户信息,一对一;

只是在SQL EXPLORER中不能用AS
直接用MAX(I.paydate)
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部