2017-02-13 8 views
0

Обновление: отредактирован псевдоним таблицы.Оптимизация запроса SQL Server 2008

Я пытаюсь найти, может ли следующий запрос быть переписан для повышения производительности. Недавно мы начали замечать огромное влияние на запрос. Таблица лиц имеет около 10 миллионов, а таблица контактов - около 17 миллионов записей.

SELECT 
    ID, NAME, DEPARTMENT, 
    CASE 
     WHEN PrimaryContact = 'MOBILE' 
      THEN (SELECT TOP 1 MOBILE 
       FROM CONTACT 
       WHERE ContactType = 'MOBILE' AND CONTACT.PID = PERSON.PID) 
      ELSE (SELECT TOP 1 HOME 
       FROM CONTACT 
       WHERE CONTACTTYPE = 'HOME' AND CONTACT.PID = PERSON.PID), 
FROM 
    PERSON 
WHERE 
    DEPARTMENT = @DEPARTMENT 

Каждый человек может иметь один/несколько мобильных/домашних телефонов в таблице контактов. Основываясь на типе первичного контакта, он должен получить только один номер телефона на основе типа PrimaryContact.

На боковой ноте мы также планируем разбить таблицу Person на основе Department.

Любые предложения по улучшению общей производительности будут высоко оценены.

Благодаря

+0

Ваш запрос настолько далек от синтаксически правилен, что это не имеет смысла. Что такое '' DETAILS'? –

+0

К сожалению, это PERSON.PID вместо DETAILS.PID – Sharmi

+0

Вы просмотрели ** планы выполнения ** для этого запроса? Что они показывают? Также: каковы ваши структуры таблиц и какие индексы уже существуют? –

ответ

0

Для этого запроса:

SELECT p.ID, p.NAME, p.DEPARTMENT, 
     (CASE WHEN p.PrimaryContact = 'MOBILE' 
      THEN (SELECT TOP 1 c.MOBILE 
        FROM CONTACT c 
        WHERE c.ContactType = 'MOBILE' AND c.PID = p.PID 
       ) 
      ELSE (SELECT TOP 1 c.HOME 
        FROM CONTACT c 
        WHERE c.CONTACTTYPE = 'HOME' AND c.PID = p.PID 
     END) 
FROM PERSON p 
WHERE p.DEPARTMENT = @DEPARTMENT; 

Вы должны начать с индексами: person(department, primarycontact, pid) и contact(pid, contacttype, home, mobile).

Обычно, когда вы используете TOP, у вас будет статья ORDER BY.

+0

Спасибо, я добавлю индекс и проверю производительность. Есть ли другая область перезаписи запроса? – Sharmi

0

Первое, почему вам нужно 10 миллионов запись в одно время? (Подкачки?)

вы можете переписать запрос, как это, исправить ошибку, очистить кэш затем запустить.

SELECT 
    ID, NAME, DEPARTMENT, 

      (SELECT TOP 1 CASE when ContactType='MOBILE' then MOBILE else Home end 
       FROM dbo.CONTACT with (nolock) 
       WHERE CONTACT.PID = PERSON.PID 
       and ((PrimaryContact = 'MOBILE' and ContactType = 'MOBILE') or (PrimaryContact != 'MOBILE' and ContactType = 'Home'))) 

FROM 
    dbo.PERSON P with (nolock) 
WHERE 
    DEPARTMENT = @DEPARTMENT 

Даже вы можете использовать внутреннее соединение с аналогичным состоянием и проверить себя.

мой указательный suggesation,

clustered index on person.PID 
clustered index on contact.PID 
non clustered index on person.DEPARTMENT include(name,PrimaryContact) 
non clustered index on contact.ContactType include(MOBILE,Home)