[英]Performance issue with correlated SQL Server query
I have a query that looks like the following, it is just entirely too slow and I don't know how to speed it up. 我有一个查询,如下所示,它完全太慢了,我不知道如何加快查询速度。 This query is currently correlated.
该查询当前是相关的。 Will a temp table to then join solve this?
临时表然后可以解决这个问题吗?
SELECT
e.ID, e.Name
FROM
Employees e
WHERE
e.Salary > (SELECT AVG(e2.Salary)
FROM Employees e2
WHERE e2.DepartmentID = e.DepartmentID)
Please try following SQL query 请尝试以下SQL查询
with cte as (
select
*,
AVG(Salary) over (partition by DepartmentID) average
from employees
)
select * from cte where Salary > average
Here you will see that I used SQL Average aggregation function with Partition By clause In order to use it I preferred a SQL CTE expression 在这里,您将看到我将SQL Average 聚合函数与Partition By子句一起使用。为了使用它,我更喜欢使用SQL CTE表达式
I would try moving the sub query into a join. 我会尝试将子查询移到联接中。 If there is an index on the
DepartmentID
that includes the salary column, then it will produce the subquery result quickly and join it to the main results. 如果
DepartmentID
上有一个包含薪金列的索引,则它将快速生成子查询结果并将其与主要结果连接。
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
It's not just the select, think of the usecase. 考虑用例,这不仅仅是选择。 You need to calculate the average salary just when you add or update an employee's salary, but you could need this query more often.
您仅在添加或更新员工的薪水时需要计算平均薪水,但是您可能更需要此查询。 There's no point in recalculating each time you do a read.
每次阅读都没有必要重新计算。
I would separate the second query, store the result in the Departments
table (I'm assuming you have one) in a field called AvgSalary
and then have the query look like: 我将分开第二个查询,将结果存储在名为
AvgSalary
的字段中的Departments
表中(假设您有一个),然后使查询看起来像:
SELECT
e.ID,
e.Name
FROM
Employees e
JOIN Departments d ON e.DepartmentID = d.DepartmentID
WHERE
e.Salary > d.AvgSalary
At first I suggest you to try CROSS APPLY here is some more info: 首先,我建议您尝试CROSS APPLY, 这里提供了更多信息:
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
If you are using SQL Server 2012 and up then you can use CTE with AVG OVER 如果您使用的是SQL Server 2012及更高版本,则可以将CTE与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
Pre-Calculate the average salary for each department and use it in further queries. 预先计算每个部门的平均工资,并在以后的查询中使用它。
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.