相关 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)
我有一个如下所示的查询,它太慢了,我不知道如何加快它的速度。此查询当前是相关的。临时 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)