2016-07-29 11 views
0

Ich habe eine Abfrage, die wie folgt aussieht, es ist einfach völlig zu langsam und ich weiß nicht, wie man es beschleunigt. Diese Abfrage ist derzeit korreliert. Wird eine temporäre Tabelle, die dann beitreten soll, dies lösen?Leistungsproblem mit korrelierten SQL Server-Abfrage

SELECT 
    e.ID, e.Name 
FROM 
    Employees e 
WHERE 
    e.Salary > (SELECT AVG(e2.Salary) 
       FROM Employees e2 
       WHERE e2.DepartmentID = e.DepartmentID) 
+1

Verwenden Sie Kreuz anwenden ist eine Option –

+2

bitte Buchungsplan, plus Tabelle Schema in der Abfrage beteiligt – TheGameiswar

Antwort

3

Bitte versuchen Sie folgende SQL-Abfrage

with cte as (
select 
    *, 
    AVG(Salary) over (partition by DepartmentID) average 
from employees 
) 
select * from cte where Salary > average 

Hier sehen Sie, dass ich SQL Durchschnitt verwenden aggregation function with Partition By Klausel um es zu benutzen ich lieber einen SQL CTE Ausdruck

0

Ich würde versuchen, die Unterabfrage in eine Verknüpfung zu verschieben. Wenn für die DepartmentID ein Index vorhanden ist, der die Gehaltsspalte enthält, wird das Unterabfrageergebnis schnell erstellt und mit den Hauptergebnissen verknüpft.

SELECT e.ID, 
     e.Name 
FROM Employees e 
INNER JOIN (
    SELECT DepartmentID, AVG(Salary) as AverageSalary 
    FROM Employees 
    GROUP BY DepartmentId 
) dptAvg ON e.DepartmentID = dptAvg.DepartmentId 
WHERE 
    e.Salary > dptAvg.AverageSalary 
0

Es ist nicht nur die Auswahl, denke an den Anwendungsfall. Sie müssen das Durchschnittsgehalt nur berechnen, wenn Sie das Gehalt eines Mitarbeiters hinzufügen oder aktualisieren, aber Sie könnten diese Abfrage häufiger benötigen. Es macht keinen Sinn, jedes Mal neu zu berechnen, wenn Sie lesen.

würde ich die zweite Abfrage trennen, speichern Sie das Ergebnis in der Departments Tabelle (Ich gehe davon aus Sie eine haben) in einem Feld namens AvgSalary und dann wie die Abfrage Blick:

SELECT 
    e.ID, 
    e.Name 
FROM 
    Employees e 
    JOIN Departments d ON e.DepartmentID = d.DepartmentID 
WHERE 
    e.Salary > d.AvgSalary 
0

Zunächst empfehle ich Ihnen CROSS APPLYhere einige weitere Informationen, um zu versuchen:

SELECT e.ID, 
     e.Name 
FROM Employees e 
CROSS APPLY (
    SELECT AVG(e2.Salary) as avgs 
    FROM Employees e2 
    WHERE e2.DepartmentID = e.DepartmentID 
    ) as p 
WHERE e.Salary > avgs 

Wenn Sie SQL Server 2012 verwenden und bis dann können Sie CTE mit AVG OVER

;WITH cte AS (
SELECT e.ID, 
     e.Name, 
     AVG(e.Salary) OVER (PARTITION BY e.DepartmentID ORDER BY e.ID) as avgs, 
     e.Salary 
FROM Employees e 
) 

SELECT ID, 
     Name 
FROM cte 
WHERE Salary > avgs 
0

Pre- verwenden Berechnen Sie das Durchschnittsgehalt für jede Abteilung und verwenden Sie es in weiteren Abfragen.