2016-09-22 1 views
0

Ich habe eine Benutzeransicht, die ich in Sql mit einer äußeren Anwendung erstellt habe, die die Menge an Jahren Erfahrung bringt der Benutzer hat nach ihren Beschäftigungsdaten zurück.SQL Server äußere Anwendung verursacht große CPU-Belastung

Wenn ich die Kosten meiner SQL-Anweisungen im Aktivitätsmonitor (SQL Enterprise Manager) überwacht, heißt es, dass dieser Teil in der Ansicht 25% eines ziemlich großen CPU-Preises im Ausführungsplan verursacht.

Ich versuche, eine effektivere Methode zu erarbeiten, diese Metrik ohne zusätzlichen Aufwand in die Ansicht zu bringen.

Hier ist die Anwendung ...

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

auf jeden Fall sind Sie tatsächlich auswählen und daher mehrere Datensätze in der Abfrage innerhalb der OUTER APPLY verbinden - Sie keine Gruppierung anwenden - wird job_history (potentiell ly) mehrere Datensätze für jeden Mitarbeiter haben? – Cato

+0

Sie müssen äußere gelten für die Funktionsaufrufe, wenn Sie keine Funktionen verwenden können Sie Joins verwenden. – ajeh

Antwort

0

Ungeprüfte aber gehen an so etwas wie dieses:

;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

Sie sind wahrscheinlich einen Index für die job_history Tabelle (userid, StartYear)

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

Ich bin mir nicht sicher, ich könnte etwas vermissen, aber, Sie scheinen zu berechnen wo rk Erfahrung für jedes Jahr, er hat es (eigentlich die Berufserfahrung zurück n-mal glaube ich), und dann zu jedem Datensatz kommt, vielleicht, wenn Sie nur die Berufserfahrung wollen jetzt

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 

, wie viele Datensätze würde die SELECT COALESCE (Jahr (getDate()) - Min (startyear), 0) AS YearsWorkExp VON dbo.job_history WHERE (userid = U.userid)

gestaltet sein, um zurückzukehren, und deshalb kommen zu? Verstehst du, was ich meine?

0

Wenn Sie gleichen Jahr Wert verwenden Jahre Erfahrung zu berechnen, dann, warum es nicht vor berechnen stattdessen Funktion des Aufrufs YEAR() und GETDATE() für jede Zeile in 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

Der Aufwand ist in der COALESCE-Funktion, Verwenden Sie stattdessen ISNULL-Funktion ISNULL (@Yr - Min (StartYear), 0) AS YearsWorkExp

+0

ISNULL hat einen geringen Leistungsvorteil. Die Umstellung von COALESCE auf ISNULL wird hier nicht der Retter sein. – Jens

Verwandte Themen