2013-08-13 2 views
1

У меня есть следующий вид, содержащий PIVOT:медленные запросы, когда Регистрация Просмотр содержит 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 применяет маску из PHONETYPE к PhoneNumber, маска (##) #### ####

Я фактически не работает Select * from tblPerson, но даже работает SELECT PersonID from tblPerson INNER JOIN .... вызывает запрос на возраст. Это было только, например.

+0

Почему вы используете функцию ROW_NUMBER, Извините, но я не вижу необходимости присваивать номера строк здесь. Исправьте меня, если я ошибаюсь, вы можете повысить эффективность, удалив назначение rownumbers. –

+0

@surajsingh Номер строки используется для возврата только трех значений, эти 3 значения затем преобразуются в столбцы в своде. – Taryn

+2

Можете ли вы опубликовать свою структуру таблицы, определение вида 'vwPhoneNumberMasked' и показать все индексы, которые у вас есть? – Taryn

ответ

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 версия).

+0

Спасибо за ваши предложения, я их просмотрю, тем временем я добавил дополнительную информацию к исходному вопросу. – Molloch

+0

@Molloch, см. Мой ответ обновлен. –

Смежные вопросы