2015-10-19 3 views
1

У меня есть этот очень старый и медленный запрос, который я пытаюсь оптимизировать, но я не уверен, что могу что-либо с ним сделать, но добавьте больше индексов в столбцы, участвующие в WHERE, JOIN и ORDER BY ,Оптимизация запросов и добавление индексов

Запрос:

SELECT TOP 400 jobticket.jobnumber, jobticket.typeform, jobticket.filename, jobticket.req_number, jobticket.reqd_del_date, jobticket.point_of_contact, jobticket.status, jobticket.DapsDate, jobticket.elpod, job_info.IDOrderMaskedStatus, job_info.job_status, job_info.SalesID, job_info.location, job_info.TOMetadataID 
FROM jobticket WITH (NOLOCK) 
INNER JOIN job_info WITH (NOLOCK) ON job_info.jobnumber = jobticket.jobnumber 
WHERE 
(
    NOT(
     (jobticket.status = 'Complete' OR jobticket.status = 'Completed') 
     and (job_info.job_status = 'Actualized' OR job_info.job_status = '' 
       OR job_info.job_status = 'Actualized Credit Billed' 
       OR job_info.job_status = 'DWAS Actualized' OR job_info.job_status = 'DWAS Actualized Credit Billed' 
      ) 
     ) 
    or 
    ((SELECT COUNT(job_status) AS Expr1 FROM tblConsolidatedBilling AS tblConsolidatedBilling_1 WITH (NOLOCK) 
     WHERE (job_status <> 'Actualized' 
     AND job_status <> 'Actualized Credit Billed') 
     AND (master_jobnumber = jobticket.jobnumber)) > 0) 
) 
and (jobticket.status != 'Waiting Approval' or (jobticket.status = 'Waiting Approval' and jobticket.DPGType is null)) 
and jobticket.typeform <> 'todpg' 
and ((job_info.isHidden <> 1 or job_info.isHidden is null) and job_info.isInConcurrentRelease is null) 
and job_info.deleted != '1' 
and jobticket.status != 'New Job' 
and jobticket.status != 'PRFYCLSFD' 

ORDER BY 
job_info.expediencyLevel DESC, 
jobticket.jobnumber DESC 

Выполнение плана: execution plan

Честно говоря, я не знаю, что делать с этим запросом.

Следует ли добавлять отдельные некластеризованные индексы ко всем столбцам, участвующим в ГДЕ СОЕДИНЕНИИ И ЗАКАЗЕ?

Есть много индексов на этих таблицах, но я не уверен, являются ли они полезны в этом запросе:

enter image description here

+0

Вы как-то автоматически создаете индексы на основе результатов советника по настройке базы данных? Или как у вас так много повторяющихся индексов ... –

+0

Я понятия не имею. Я пытаюсь очистить беспорядок :) – Angelina

ответ

1

Глядя на этот SQL, я не вижу каких-либо четких критериев, что является используется для извлечения строк. Похоже, это просто исключает много строк с разными критериями. Я предполагаю, что билеты обычно заканчиваются в состоянии, в котором находится большинство строк, и они не включены в результаты?

Проблема заключается в том, что на самом деле у нее нет четких критериев для этого, и в ней есть много разных правил, поэтому он заканчивает выполнение кластеризованного поиска по индексу + ключевой поиск для всех строк. Сканирование начинается с jobinfo, но я не уверен, что это будет иметь значение, если оно начнется с jobticket.

Удаление большинства индексов, вероятно, является хорошим местом для начала, но оно не ускорит выбор вообще.

Запрос выглядит довольно сложно, поэтому я предполагаю, что вы не можете создать индексный указатель, который будет содержать эти данные. Это может помочь предположить, что этот запрос выполняется часто, и данные не так сильно изменены (и накладные расходы на поддержание огромного количества индексов были бы удалены), но это может быть невозможно.

Еще одна идея - исследовать правила, когда строки могут быть исключены, и есть ли возможность иметь более четкие правила для этого, поэтому его можно индексировать, возможно, добавив в таблицу постоянный вычисленный столбец.

Вы не указали, как долго это происходит на самом деле, и сколько строк в таблицах, так что все в принципе просто догадка. Включение большего количества данных + статистика io-вывода в вопрос может помочь.

пс. Я лично не рекомендую использовать NOLOCK, кроме как в особых случаях, потому что это может вызвать проблемы, которые действительно трудно решить, например, чтение одних и тех же данных более одного раза или полное переключение строк.

+1

Для индексированного представления это может даже помочь, если вы можете создать тот, который объединяет jobinfo и jobticket, так как я предполагаю, что объединение этих таблиц + ключевой поиск является причиной медленности. –

+1

В случае, если индексированное представление не будет работать, определенно некоторые отфильтрованные индексы помогут. Главной причиной боли в этом, как вы упомянули, является четкая изоляция условий фильтрации. Оптимистический подход к фильтрам может дать более быстрый ответ, чем пессимистический подход. Возможно, что-то так же просто, как перенос фильтров JobInfo в «Присоединиться», а не в тех случаях, когда условия могут быть полезны. –

+0

@BradD Что вы подразумеваете, перемещая фильтры JobInfo в JOIN? – Angelina

1

Простым решением было бы сделать индексы на job_info и tblConsolidatedBilling покрытием, потому что тонна времени тратится на ключевые поиски там. Это должно привести к ускорению целочисленного коэффициента. Если этого недостаточно, нам нужно исследовать дальше.

+0

следует создавать индексы для каждого из этих столбцов в job_info и tblConsolidatedBilling tables? – Angelina

+0

Каждая таблица должна иметь один индекс, который имеет все столбцы, необходимые для этого запроса. – usr

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