Reputation: 9
I have a query which runs slower.
SELECT *
FROM [Obe].[dbo].[vFan] P
OUTER APPLY
(SELECT TOP 1 [CT_XY]
FROM [Obe].[dbo].[vFan]
WHERE [row_num] <= P.[row_num]
AND [CT_XY] IS NOT NULL
AND [CT_XY] != 0
ORDER BY [row_num] DESC) Q
OUTER APPLY
(SELECT TOP 1 [CT_CR1]
FROM [Obe].[dbo].[vFan]
WHERE [row_num] <= P.[row_num]
AND [CT_CR1] IS NOT NULL
AND [CT_CR1] != 0
ORDER BY [row_num] DESC) R
OUTER APPLY
(SELECT TOP 1 [CT_CR2]
FROM [Obe].[dbo].[vFan]
WHERE [row_num] <= P.[row_num]
AND [CT_CR2] IS NOT NULL
AND [CT_CR2] != 0
ORDER BY [row_num] DESC) S
ORDER BY
P.[row_num] ASC
Order By inside the Outer Apply is very costly, is there any better way to write this query ?
Upvotes: 0
Views: 111
Reputation: 1269563
From what I can tell in the code, you seem to be implementing a variation of lag(ignore nulls)
.
Here is a better way:
select f.*,
max(ct_xy) over (partition by rn_xy) as new_ct_xy,
max(rn_cr1) over (partition by rn_cr1) as new_rn_cr1,
max(rn_cr2) over (partition by rn_cr2) as new_rn_cr2
from (select f.*,
sum(case when CT_XY is not null and CT_XY <> 0
then row_num
end) over (order by row_num) as rn_xy,
sum(case when CT_CR1 is not null and CT_CR1 <> 0
then row_num
end) over (order by row_num) as rn_cr1,
sum(case when CT_CR2 is not null and CT_CR2 <> 0
then row_num
end) over (order by row_num) as rn_cr2
from vfan f
) f;
Also note that in many databases the "v" in vfan
would suggest a view. That might be the cause of the performance issues.
Upvotes: 1
Reputation: 38094
When you use ORDER BY
, SQL Server must compute all rows, sort then and only then can it give you the rows that you asked for.
So it would be great to add indexes for fields used in WHERE
statement such as CT_XY
, CT_CR1
, CT_CR2
.
UPDATE:
You should not add indexes to view, it is necessary to add indexes to the underlying table. Your query will use the indexes, where appropriate, on the underlying tables the view itself refers to.
Upvotes: 0