相关 SQL 服务器查询的性能问题

Performance issue with correlated SQL Server query

我有一个如下所示的查询,它太慢了,我不知道如何加快它的速度。此查询当前是相关的。临时 table 然后加入会解决这个问题吗?

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

我会尝试将子查询移动到连接中。如果 DepartmentID 上有包含 salary 列的索引,那么它将快速生成子查询结果并将其连接到主结果。

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

不仅仅是 select,想想用例。您需要在添加或更新员工工资时计算平均工资,但您可能更频繁地需要此查询。每次读取都重新计算是没有意义的。

我会分开第二个查询,将结果存储在 Departments table(我假设你有一个)中一个名为 AvgSalary 的字段中,然后进行查询看起来像:

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

请尝试以下SQL查询

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

在这里你会看到我使用了 SQL Average aggregation function with Partition By 子句 为了使用它,我更喜欢 SQL CTE 表达式

首先我建议你试试CROSS APPLY here更多信息:

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

如果您使用的是 SQL Server 2012 及更高版本,那么您可以使用 CTE with 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

预先计算每个部门的平均工资,用于进一步查询。

 SELECT AVG(e2.Salary) as avgSalary,DepartmentID into #t
      FROM Employees 
      group by DepartmentID

SELECT e.ID, 
       e.Name
FROM
    Employees e
WHERE
    e.Salary > (
      SELECT avgSalary
      FROM #t e2
      WHERE e2.DepartmentID = e.DepartmentID)