让我告诉你我的代码。
这是我的功能 这让我回到了约会时间。
ALTER FUNCTION GoldenMemebr(@clubid uniqueidentifier ) returns datetime
WITH SCHEMABINDING
as
begin
DECLARE @TEMP TABLE
(
TRANSTIME DATETIME,
TOTSCORE BIGINT,
CLUBID uniqueidentifier
)
INSERT INTO @TEMP (CLUBID,TRANSTIME,TOTSCORE)
SELECT ClubProfileId, TransactionTimeStamp,
SUM(Points) OVER (ORDER BY TransactionTimeStamp) totalamount
FROM
dbo.CardTransaction CT
inner join dbo.CardTransactionLog CL
on CL.CardTransactionLogId = CT.CardTransactionLogId
and ClubProfileId = @clubid
order by CL.TransactionTimeStamp
declare @ti datetime
set @ti =
(
SELECT top 1 TRANSTIME
FROM @TEMP
WHERE TOTSCORE >= 12000
order by TRANSTIME asc
)
return @ti
end
这是我的查询
select FirstName,LastName,
SUM(Points) as score, dbo.GoldenMemebr(cp.ClubProfileId) as ExactTime
from ClubProfile cp join CardTransaction ct
on ct.ClubProfileId = cp.ClubProfileId
where MembershipType = 1
group by FirstName,LastName,dbo.GoldenMemebr(cp.ClubProfileId)
此查询需要14秒才能获得38条记录(非常糟糕)
我怎样才能优化它?
答案 0 :(得分:0)
不创建和填充临时表并删除无用的" ORDER BY"我试图改善你的功能:
ALTER FUNCTION GoldenMemebr
(
@clubid uniqueidentifier
) returns datetime
WITH SCHEMABINDING
as
begin
;WITH CTE AS
(
SELECT
TransactionTimeStamp,
SUM(Points) OVER (ORDER BY TransactionTimeStamp) totalamount
FROM
dbo.CardTransaction CT
JOIN dbo.CardTransactionLog CL
ON
CL.CardTransactionLogId = CT.CardTransactionLogId and
ClubProfileId = @clubid
)
SELECT top 1 @ti = TransactionTimeStamp
FROM CTE
WHERE totalamount >= 12000
ORDER BY totalamount asc
RETURN @ti
end
在TransactionTimeStamp和CardTransactionLogId上拥有索引也可能会提高性能。
答案 1 :(得分:0)
如何将此函数更改为内联表值函数呢?
看看这是否有助于指明您的方向。请注意,您必须首先删除您的功能,因为您无法进行更改并将其从标量更改为iTVF。
ALTER FUNCTION GoldenMemebr(@clubid uniqueidentifier ) returns table
WITH SCHEMABINDING as
RETURN
with Totals as
(
SELECT TransactionTimeStamp
, SUM(Points) OVER (ORDER BY TransactionTimeStamp) as totalamount
FROM dbo.CardTransaction CT
inner join dbo.CardTransactionLog CL on CL.CardTransactionLogId = CT.CardTransactionLogId
and ClubProfileId = @clubid
)
select top 1 TransactionTimeStamp
from Totals
where totalamount > 12000
order by CL.TransactionTimeStamp
GO
select FirstName
, LastName
, SUM(Points) as score
, gm.TransactionTimeStamp as ExactTime
from ClubProfile cp
join CardTransaction ct on ct.ClubProfileId = cp.ClubProfileId
cross apply dbo.GoldenMember(cp.ClubProfileId) gm
where MembershipType = 1
group by FirstName
, LastName
, gm.TransactionTimeStamp
答案 2 :(得分:0)
您的代码很慢,因为它正在执行RBAR(按行Agonizing Row)操作,因为为每个frikkin行调用了该函数。尝试摆脱函数并将整个逻辑包装到查询中。这是我的尝试(虽然未经测试)
select MIN(TRANSTIME) TransTime, ClubProfileId into #temp from
(
SELECT ClubProfileId, TransactionTimeStamp TransTime,
SUM(Points) OVER (ORDER BY TransactionTimeStamp) totalamount
FROM
dbo.CardTransaction CT
inner join dbo.CardTransactionLog CL
on CL.CardTransactionLogId = CT.CardTransactionLogId
)A where totalamount >= 12000
create index ix_id on #temp(ClubProfileId) include (TRANSTIME)
select FirstName
,LastName
,SUM(Points) as score
,t.TransTime ExactTime
from ClubProfile cp join CardTransaction ct
on ct.ClubProfileId = cp.ClubProfileId
join #temp t on t.ClubProfileId = cp.ClubProfileId
where MembershipType = 1
group by FirstName,LastName,t.TransTime
我更喜欢CTE上的临时表,因为它提供了重用的灵活性,并且可以在其上添加索引。