我有以下包含PIVOT的视图:
CREATE VIEW [vwPhoneNumberByPref]
AS
SELECT * FROM(
SELECT ObjectKey, ObjectTypeName,r_id,MaskedNumber FROM (
SELECT * ,ROW_NUMBER() OVER (PARTITION BY ObjectKey, ObjectTypeName ORDER BY preference) as r_id
FROM vwPhoneNumberMasked ) AS a WHERE r_id<=3
)AS P
PIVOT(
MAX(MaskedNumber) FOR r_id in ([1],[2],[3])
)AS Pvt
当我使用WHERE ObjectKey = 1234
运行它时会立即返回结果。当我在连接中使用此查询时:
Select *
from tblPerson p
inner join
vwPhoneNumberByPref ph on p.PersonID = ph.ObjectKey
大约需要10秒钟,并且在执行计划中,正在对超过200,000行进行排序。
如果未在连接中使用,则会在单行上执行“排序”。我尝试使用CROSS APPLY
进行连接,这使得它稍微快一些,但仍然需要太长时间,并且仍在排序200,000多行。
如何改善表现?
其他信息:
CREATE VIEW [vwPhoneNumberMasked] AS
SELECT ph.ObjectTypeName, ph.ObjectKey, dbo.ApplyMask(ph.PhoneNumber, pt.Mask), ph.Preference
FROM tblPhoneNumber ph inner join tblPhoneType pt on
ph.PhoneTypeName = pt.Name
WHERE ph.isDeleted = 0
GO
CREATE TABLE tblPhoneType
Name varchar(20) NOT NULL,
Mask varchar(20) NOT NULL
GO
tblPhoneNumber
ObjectTypeName, ObjectKey, Preference, isDeleted
上有一个索引
函数dbo.ApplyMask
将MaskType从PhoneType应用到PhoneNumber,掩码为(##) #### ####
我实际上并未运行Select * from tblPerson
,但即使运行SELECT PersonID from tblPerson INNER JOIN ....
也会导致查询耗时。这仅仅是例如。
答案 0 :(得分:0)
在您提供更多信息后,我建议您尝试以下操作。在表tblPhoneNumber
上添加索引:
create index ix_tblPhoneNumber_1
on tblPhoneNumber (isDeleted, ObjectKey, ObjectTypeName, Preference)
include (PhoneNumber, PhoneTypeName)
在表tblPhoneType
上添加(如果没有)
create unique clustered index ix_tblPhoneType
on tblPhoneType (PhoneTypeName)
或
create unique index ix_tblPhoneType
on tblPhoneType (PhoneTypeName) include (Mask)
将您的vwPhoneNumberMasked
视图更改为:
ALTER VIEW [vwPhoneNumberMasked] AS
SELECT ph.ObjectTypeName, ph.ObjectKey, mp.Value as MaskedNumber, ph.Preference
FROM tblPhoneNumber ph
inner /*loop*/ join tblPhoneType pt on ph.PhoneTypeName = pt.Name
cross apply ftMaskPhone(ph.PhoneNumber, pt.Mask) mp
WHERE ph.isDeleted = 0
其中ftMaskPhone
来自 this answer (请使用方法2 版本)。