SQL Server : 테이블 크기 변경과 쿼리 실행 속도 간의 관계 이해

5754 단어 SQLServerDB

배경



서비스 성장과 함께 데이터는 계속 증가합니다. 테이블의 레코드수가 늘어나면, 「인덱스의 구조는 어떻게 바뀌는가」를 이해할 수 있으면 「테이블 사이즈의 변화에 ​​따라 쿼리의 실행 속도는 어떻게 바뀌는지」에 대해 예측할 수 있게 되므로, 설명하고 싶습니다.

레코드 수의 차이로 인한 인덱스 구조의 변화 확인



테이블 정의는 동일하며 레코드 수만 다른 DB를 3개 준비합니다.


그런 다음 각 DB에서 인덱스 재구성을 수행하여 조각화를 최대한 줄인 상태로 만듭니다.
use MyTuningDB_small
alter index PK_MemberEMail on MemberEMail rebuild
go

use MyTuningDB_middle
alter index PK_MemberEMail on MemberEMail rebuild
go

use MyTuningDB_large
alter index PK_MemberEMail on MemberEMail rebuild
go

그 후, 각 DB마다 인덱스의 구조를 확인합니다.
DECLARE @OBJECT_ID int
set @OBJECT_ID = OBJECT_ID('MemberEMail')

SELECT
index_id
,index_type_desc
,index_depth
,index_level
,page_count
,record_count
FROM sys.dm_db_index_physical_stats (DB_ID(), @OBJECT_ID, NULL , NULL, 'DETAILED') as A
JOIN sys.objects as B on A.object_id = B.object_id
ORDER BY index_id, index_level

결과는 다음과 같습니다.


이 결과로부터 다음을 알 수 있습니다.
  • 1000 만 단위의 레코드 수 차이에서도 트리의 깊이는 거의 동일합니다 (index_depth = 3 or 4)
  • 리프 노드의 페이지 수 (page_count)는 레코드 수에 거의 비례합니다.

    레코드 수의 차이로 인한 쿼리 실행 속도의 변화 확인



    Index Scan과 Index Seek 모두에서 테이블의 레코드 수가 증가함에 따라 실행 시간이 어떻게 변화하는지를 측정하고 정리했습니다.

    색인 스캔 시




    ↑와 같이, Index Scan로 쿼리 실행되는 경우의 테이블 레코드수의 변화와 실행 속도의 관계를 계측해 이하에 정리했습니다.

    실행 시간 요약





    Index Scan일 때의 쿼리 실행 속도 변화의 포인트


  • 레코드 수가 많을수록 "논리 읽기 수"가 증가합니다.
  • 리프 노드의 페이지 수와 거의 일치

  • 레코드수가 늘어날수록 여분의 실행시간이 증가
  • 1.5초 → 3초 → 5초


  • Index Seek일 때




    ↑와 같이, Index Seek로 쿼리 실행되는 경우의 테이블 레코드수의 변화와 실행 속도의 관계를 계측해 이하에 정리했습니다.

    실행 시간 요약





    Index Seek일 때의 쿼리 실행 속도 변화의 포인트


  • 레코드 수가 증가해도 "논리 읽기 수"가 거의 동일합니다.
  • 인덱스의 계층 수와 거의 일치

  • 따라서 레코드가 크게 증가해도 실행 시간은 거의 동일합니다.
  • Index Seek의 강력한 특징


  • 요약



    먼저 레코드 수가 증가함에 따라 인덱스 구조가 어떻게 변경되는지 확인했습니다.
    1000만 단위로 레코드가 늘어나도 쿼리의 계층수(깊이)는 거의 변하지 않고, 한편, 리프 페이지수는 레코드수에 비례하여 증가해 가는 경향을 확인할 수 있었습니다.

    다음으로 Index Scan/Index Seek에서 레코드 수 변화가 미치는 실행 시간에 미치는 영향에 대해 확인했습니다. Index Scan은 레코드 수가 늘어나면 실행 시간도 늘어나는 반면, Index Seek에 대해서는 레코드 수가 늘어도 실행 시간은 늘지 않는 것을 확인할 수 있었습니다.

    이것으로부터, 데이터량 증가에 수반하는 쿼리 실행 시간의 변화를 추정할 때는, 「그 쿼리의 실행은 Scan인가, Seek인가」를 이해해 두는 것이 중요하다는 것을 알 수 있습니다.

    "데이터 량이 증가했기 때문에 느려졌거나 느려질 것"이 아니라,
  • "데이터의 양이 증가해도 Seek 처리이므로 속도는 변하지 않아야한다"
  • "데이터 량이 증가하면 스캔 처리이므로 점차 느려질 우려가 있습니다."

    라고 하는 추정을 할 수 있으면 부하에 관한 미래 예측의 정밀도가 올라간다고 생각합니다.
  • 좋은 웹페이지 즐겨찾기