2014-09-22 6 views
2

나는 직원 매김 직원의 이름으로 정렬 지원하기 위해 쿼리 아래가 매개 변수 rowNumAlias이 쿼리가 가진 내 SQL 서버 데이터베이스에 약 7 초 복용 한 100이 쿼리의 성능 튜닝?

사이의 모든 정수가 될 수

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 ? 

1 백만 레코드. 쿼리 실행 시간을 최소화 할 수있는 방법이 있습니까?

+0

[실행 계획 수립] (http://stackoverflow.com/questions/7359702/how-do-i-obtain-a-query-execution-plan)이 필요합니다. 이것은 쿼리의 가장 느린 부분이 무엇인지 알려주고 심지어 쿼리 속도를 높이는 데 사용할 수있는 인덱스를 제안합니다. – Justin

+0

어떤 버전의 SQL Server입니까? 2012 년 이후 + 페이지 매김을 수행하는 더 좋은 방법이 있습니다. 쿼리 실행 계획은 무엇입니까? 어쩌면 당신은 인덱스가 누락되었습니다 (예를 들어 Employee.name에서)? – jpw

+0

pk/fk가 ​​인덱싱된다고 가정하면 직원 이름 순서가 성능에 영향을 미칠 수 있습니다. 그래서 그것의 이름은 색인을 가지고 있습니까? (또는 사용 가능한 경우 SQL Server 2012의 더 나은 페이지 매김 구문 사용) –

답변

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 ? 
+0

row_number()를 select 절의 상관 하위 쿼리로 실행하도록 제안 하시겠습니까? 확실하지 않습니다 심지어 –

+0

이 쿼리를위한 다른 해결책이 있는지 모르겠습니다. – Iulian

+0

하지만 기존 제안을 어떻게 개선 할 예정입니까? 만약 당신이 확실하지 않다면 나는 당신이 "downvoted"를 얻을 것이라고 제안하지 않을 것을 제안 할 것이다 –

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 ? 
+0

그것도 좋은 제안을했다. 같은 실행 시간 – user3198603

+0

거의 같은 결과 – user3198603

1

당신은 페이지 매김을 수행 할 ORDER BY ... OFFSET ... FETCH ... 구문을 사용할 수 있습니다 2012+ SQL 서버에있는 경우 :

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 ?; 
+0

거의 같은 결과 – user3198603

+0

@ user3198603 그건 이상합니다. 내 실행 계획에 따르면 cte 쿼리의 비용 (일괄 처리와 관련하여)은 67 %의 비용 (일괄 처리와 관련이 있음)을 가진 허용 된 응답과 비교하여 33 %입니다. employee.name 오름차순에 대해 비 클러스터형 인덱스로 시도 했습니까? – jpw