2016-09-22 2 views
0

У меня есть пользовательский вид, который я создал в sql с внешним применением, который возвращает многолетний опыт работы пользователя в соответствии с их записями о занятости.Внешние приложения SQL Server, вызывающие основную нагрузку на процессор

Когда я отслеживал стоимость моих операторов SQL в мониторе активности (диспетчер SQL Enterprise), он говорит, что эта часть в представлении вызывает 25% довольно большой стоимости ЦП в плане выполнения.

Я пытаюсь разработать более эффективный способ приведения этой метрики в представление без дополнительных накладных расходов.

ЗДЕСЬ это применить ...

SELECT * 
FROM users U <BLAH BLAH BLAH> OUTER apply 
    (SELECT COALESCE (Year(Getdate()) - Min(StartYear), 0) AS YearsWorkExp 
    FROM dbo.job_history 
    WHERE (userid = U.userid)) AS WorkExp 
+0

В любом случае, вы фактически выбираете и, следовательно, соединяете несколько записей в запросе внутри OUTER APPLY - вы не применяете какую-либо группировку - будет job_history (потенциальный ly) имеют несколько записей для каждого сотрудника? – Cato

+0

Вам нужно, чтобы внешняя применялась для вызовов функций, когда вы не используете функции, которые вы можете использовать для соединения. – ajeh

ответ

0

непроверенная, но есть пойти на что-то вроде этого:

;WITH base AS 
(
    SELECT 
     userid, 
     MIN(StartYear) StartYear 
    FROM dbo.job_history 
    GROUP BY userid 
)  
SELECT u.* 
    , YEAR(GETDATE()) - ISNULL(b.StartYear, YEAR(Getdate())) AS YearsWorkExp 
FROM users u 
LEFT OUTER JOIN base b 
ON b.userid = u.userid; 
0

Вы, вероятно, не хватает индекс на job_history таблицы (userid, StartYear)

create index idx_job_history_userid_StartYear on dbo.job_history (userid, StartYear) 
0

Я не уверен, я мог бы что-то упустить, но вы, кажется, вычисляете wo гк опыт за каждый год он был там (на самом деле опыт работы вернулся п раз, я думаю), а затем присоединение к каждой записи, может быть, если вы просто хотите, опыт работы в настоящее время

SELECT * 
FROM users U <BLAH BLAH BLAH> OUTER apply 
    (SELECT TOP 1 COALESCE (Year(Getdate()) - StartYear, 0) AS YearsWorkExp 
    FROM dbo.job_history 
    WHERE (userid = U.userid) ORDER BY StartYear DESC) AS WorkExp 

сколько записей бы ВЫБРАТЬ COALESCE (Год (GetDate()) - Min (StartYear), 0) AS YearsWorkExp ОТ dbo.job_history WHERE (идентификатор пользователя = U.userid)

быть разработаны, чтобы вернуться, и поэтому присоединиться к? Вы видите, что я имею в виду?

0

Если вы используете такое же значение Год для расчета Годы опыта, то почему бы не вычислить его раньше вместо вызова функции YEAR() и GETDATE() для каждой строки в OUTER APPLY

DECLARE @Yr INT = Year(Getdate()); 
SELECT * 
FROM users U <BLAH BLAH BLAH> 
OUTER apply 
(
    SELECT COALESCE (@Yr - Min(StartYear), 0) AS YearsWorkExp 
    FROM dbo.job_history 
    WHERE (userid = U.userid) 
) AS WorkExp 
0

накладные расходы в функции COALESCE, используйте функцию ISNULL вместо ISNULL (@Yr - Min (StartYear), 0) AS YearsWorkExp

+0

ISNULL имеет незначительное преимущество в производительности. Изменение COALESCE ISNULL здесь не будет спасителем. – Jens

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