我有Access 2003 with SQL后端。
此查询需要10分钟才能执行,如果我取出Exists部分需要10秒钟。
我不能把它作为直通查询放在SQL中,因为我需要在Access子报告中使用它。
任何想法如何改善执行时间??
SELECT DailyLeaveLedger.dldEmployeeID,
Sum(IIf([tolAnnualLeaveType]<>0,1,0)) AS ALDays,
Sum(IIf([tolPersonalLeaveType]<>0,1,0)) AS PLDays,
Sum(IIf([tolPublicHolidayType]<>0,1,0)) AS PHDays,
DailyLeaveLedger.dldPHID
FROM (DailyLeaveLedger
INNER JOIN Employees ON DailyLeaveLedger.dldEmployeeID = Employees.EmployeeID)
INNER JOIN TypeOfLesterLeave ON DailyLeaveLedger.dldLeaveType = TypeOfLesterLeave.tolID
WHERE (((DailyLeaveLedger.dldAuthDecline)=1) AND
((DailyLeaveLedger.dldAuthorisedBy) Is Not Null) AND
((DailyLeaveLedger.dldReleaseToPayroll)=True) AND
((IIf([forms]![TransferTBRToPayrollForm]![chkOnlyPayLeave]=True,
Exists (SELECT DISTINCT InvoiceHeader.InvDate
FROM (InvoiceHeader
INNER JOIN ReceiptDetail ON InvoiceHeader.InvNumber = ReceiptDetail.RDInvNumber)
INNER JOIN [Work Codes] ON ReceiptDetail.RDWorkCodeID = [Work Codes].WorkCodeID
WHERE ((ReceiptDetail.RDPayRun=0 Or
ReceiptDetail.RDPayRun Is Null) AND
(ReceiptDetail.RDRctToPayrollFlag=0) AND
([Work Codes].WorkCodePayrollAccount1<>0) AND
(InvoiceHeader.EmployeeID = DailyLeaveLedger.dldEmployeeID) AND
(DailyLeaveLedger.dldLeaveDate > DateAdd("ww", -InvoiceHeader.InvWeeksOfPay, InvoiceHeader.InvBeginDate)) AND
(DailyLeaveLedger.dldLeaveDate <= InvoiceHeader.InvBeginDate)))
,True))=True))
GROUP BY DailyLeaveLedger.dldEmployeeID, DailyLeaveLedger.dldPHID
HAVING (((DailyLeaveLedger.dldPHID) Is Null));
答案 0 :(得分:2)
让我们一次做一点。当我发现更多时,我会更新答案:
首先是简单的,删除select中的iif语句如下。
替换
SELECT DailyLeaveLedger.dldEmployeeID,
Sum(IIf([tolAnnualLeaveType]<>0,1,0)) AS ALDays,
Sum(IIf([tolPersonalLeaveType]<>0,1,0)) AS PLDays,
Sum(IIf([tolPublicHolidayType]<>0,1,0)) AS PHDays,
DailyLeaveLedger.dldPHID
与
SELECT DailyLeaveLedger.dldEmployeeID,
Sum([tolAnnualLeaveType] *-1) AS ALDays,
Sum([tolPersonalLeaveType] *-1) AS PLDays,
Sum([tolPublicHolidayType] *-1) AS PHDays,
DailyLeaveLedger.dldPHID
这将为您提供最低限度的改进。一旦我解开剩下的部分,我会给你一些更有影响力的。
其余部分是如此邪恶的混乱,我放弃试图解开它。但是,让我为您提供一些指导,说明您需要在一般意义上做什么而不是确切的代码。
基本上您需要做的是将此部分拉入主查询的连接而不是使用子查询。
(IIf([forms]![TransferTBRToPayrollForm]![chkOnlyPayLeave]=True,
Exists (SELECT DISTINCT InvoiceHeader.InvDate
FROM (InvoiceHeader
INNER JOIN ReceiptDetail ON InvoiceHeader.InvNumber = ReceiptDetail.RDInvNumber)
INNER JOIN [Work Codes] ON ReceiptDetail.RDWorkCodeID = [Work Codes].WorkCodeID
WHERE ((ReceiptDetail.RDPayRun=0 Or ReceiptDetail.RDPayRun Is Null) AND
(ReceiptDetail.RDRctToPayrollFlag=0) AND
([Work Codes].WorkCodePayrollAccount1<>0) AND
(InvoiceHeader.EmployeeID = DailyLeaveLedger.dldEmployeeID) AND
(DailyLeaveLedger.dldLeaveDate > DateAdd("ww", -InvoiceHeader.InvWeeksOfPay, InvoiceHeader.InvBeginDate)) AND
(DailyLeaveLedger.dldLeaveDate <= InvoiceHeader.InvBeginDate)))
,True))=True))
这有意义吗?坦率地说,如果你不理解为什么抱怨将这个更改为传递,我有点担心你能够解决这个问题。它与从子报告中调用它无关,而更多与您使用VBA函数的事实有关。
答案 1 :(得分:0)
请提供格式化查询以便更好地理解.. 我已完成查询,发现原因可能是由于 EXIST 语句,其中您使用 InvoiceHeader.InvDate 的 Invinyct
如果您仅使用Exist子句记录存在,那么我不知道您的具体情况,然后使用count(InvoiceHeader.InvDate)代替不同的InvoiceHeader.InvDate 我认为那时表现会增加..
答案 2 :(得分:0)
不确定Access正在做什么,但子报告将对主报告中的每条记录执行查询,因此我会在运行报告之前将此查询转储到表中。然后使用该表作为子报告记录源。
我在季度声明报告中使用了这个报告,该报告有几个子报告,它将时间从几个小时缩短到不到20分钟。