这个查询的性能调优?

时间:2014-09-22 09:15:39

标签: sql sql-server database sql-optimization

我有以下查询来支持按员工姓名

排序的员工分页
SELECT rowNumAlias
    ,Employee.employeeId
    ,Employee.NAME
FROM (
    SELECT row_number() OVER (
            ORDER BY Employee.NAME ASC
            ) rowNumAlias
        ,employeeId
        ,NAME
    FROM Employee
    ) employeeData
INNER JOIN Employee ON Employee.employeeId = employeeData.employeeId
WHERE rowNumAlias BETWEEN ? AND ?

其中参数rowNumAlias可以是1到100之间的任何整数

这个查询在我的sql server数据库上花了大约7秒钟,有100万条记录。 有没有办法可以最大限度地缩短查询执行时间?

3 个答案:

答案 0 :(得分:1)

您可以尝试这样:

SELECT * FROM (
SELECT (SELECT row_number() OVER (ORDER BY e2.NAME ASC) FROM Employee e2 WHERE Employee.employeeId = E2.employeeId) rowNumAlias,
    ,Employee.employeeId
    ,Employee.NAME
FROM Employee 
) e3 WHERE e3.rowNumAlias BETWEEN ? AND ?

答案 1 :(得分:1)

您可以尝试使用CTE。

;WITH employeeData as 
(
    SELECT row_number() OVER (ORDER BY Employee.NAME ASC) rowNumAlias,
    employeeId,
    NAME
    FROM Employee
)
SELECT employeeData.rowNumAlias,
employeeData.employeeId,
employeeData.NAME
FROM employeeData
INNER JOIN Employee ON Employee.employeeId = employeeData.employeeId
WHERE rowNumAlias BETWEEN ? AND ?

答案 2 :(得分:1)

如果您使用的是SQL Server 2012+,则可以使用ORDER BY ... OFFSET ... FETCH ...语法进行分页:

SELECT EmployeeId, Name    
FROM Employee
ORDER BY Employee.Name ASC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY

OFFSET指定要跳过的行数和FETCH NEXT要获取的行数。请参阅documentation

在早期版本中,您应该能够通过使用公用表表达式获得更好的性能(使用适当的索引,此查询看起来就像根据我的执行计划暂停原始时间一样执行):

;With cte (rownum, employeeid, name)  as (
    SELECT 
       rownum = row_number() OVER (ORDER BY employee.name ASC),
        employeeid, 
       name
    FROM employee
)

SELECT rownum, employeeid, name
FROM cte
WHERE rownum BETWEEN ? AND ?;