SQL 데이터베이스 실제 파일 조각화


19

DBA로 고려해야 할 가지 종류의 조각화 가 실제로 있다는 것을 알고 있습니다.

  1. 인덱스 클러스터 된 인덱스 (테이블) 조각을 포함하여 SQL 데이터 파일의 단편화. DBCC SHOWCONTIG (SQL 2000) 또는 sys.dm_ db_ index_ physical_ stats (2005+)를 사용하여이를 식별하십시오.

  2. SQL 로그 파일 내에서 VLF 조각화 DBCC LOGINFO를 실행하여 각 SQL 로그 파일에 몇 개의 VLF가 있는지 확인하십시오.

  3. 하드 드라이브에있는 데이터베이스 파일의 실제 파일 조각화 Windows에서 "디스크 조각 모음"유틸리티를 사용하여이를 진단하십시오. ( 이 훌륭한 블로그 게시물에서 영감을 얻음 )

인덱스 조각화에 많은주의를 기울이고 있습니다 ( Paul Randall 의이 훌륭한 Serverfault 답변 참조 ). 제 질문의 초점이 아닙니다.

내가 할 수 알고 않도록 자주가 성장하고 정신과에서이 단편화가 가장 자주 발생하기 때문에, 합리적인 예상 데이터 파일 및 로그 크기를 계획하여 데이터베이스가 원래 생성 물리적 조각 (그리고 VLF 조각을),하지만 난 방법에 대한 몇 가지 질문이 수정 일단 식별되면 물리적 조각화 :

  • 우선, 물리적 조각화는 Enterprise SAN에서도 관련이 있습니까? SAN 드라이브에서 Windows 조각 모음을 사용해야합니까, 아니면 SAN 팀에서 내부 조각 모음 유틸리티를 사용해야합니까? SAN 드라이브에서 실행할 때 Windows 도구에서 얻은 조각화 분석도 정확 합니까?

  • SQL 성능에 대한 물리적 조각화는 얼마나 큰 문제입니까? (이전 질문의 결과를 보류하면서 내부 드라이브 배열을 가정 해 봅시다.) 내부 인덱스 조각화보다 더 큰 거래입니까? 아니면 실제로 같은 종류 의 문제입니까 (드라이브는 순차적 읽기 대신 임의 읽기를 수행해야합니다)

  • 드라이브가 물리적으로 조각화 된 경우 조각 모음 (또는 재구성) 색인이 시간 낭비입니까? 다른 문제를 해결하기 전에 문제를 해결해야합니까?

  • 프로덕션 SQL 상자에서 실제 파일 조각화를 해결하는 가장 좋은 방법은 무엇입니까? SQL 서비스를 끄고 Windows 조각 모음을 실행할 수 있다는 것도 알고 있지만 전체 백업을 수행하고 데이터베이스를 삭제 한 다음 백업에서 빈 드라이브로 복원하는 기술에 대해서도 들었습니다. 후자의 기술이 권장됩니까? 이 같은 백업에서 복원 하는가 도의 내부 인덱스 조각을 제거 처음부터 빌드 인덱스? 아니면 단순히 백업을 수행 할 때와 같은 순서로 페이지 순서를 반환합니까? (필요한 경우 압축을 통해 Quest Lightspeed 백업을 사용하고 있습니다.)

업데이트 : 지금까지 SAN 드라이브 조각 모음 (NO) 여부와 물리적 조각난 드라이브에서 인덱스 조각 모음이 여전히 가치가 있는지에 대한 좋은 답변 (YES).

다른 사람이 실제로 조각 모음을 수행하는 가장 좋은 방법에 대해 고민하고 있습니까? 또는 500GB 정도의 큰 조각난 드라이브를 조각 모음하는 데 걸리는 예상 시간은 얼마입니까? SQL 서버가 다운 될 때가 되었기 때문입니다.

또한 물리적 조각화를 수정하여 수행 한 SQL 성능 개선에 대한 일화 정보가있는 사람도 유용합니다. Mike의 블로그 게시물 은 문제를 발견하는 것에 대해 이야기하지만 어떤 종류의 개선에 대해서는 구체적이지 않습니다.

답변:


9

이 기사에서는 SAN 드라이브 조각 모음에 대한 훌륭한 개요를 제공한다고 생각합니다.

http://www.las-solanas.com/storage_virtualization/san_volume_defragmentation.php

기본 요점은 LUN을 제시 할 때 SAN에 의해 ​​위치가 가상화 된 경우 디스크의 블록의 물리적 위치를 상호 연관시키기 어렵 기 때문에 SAN 스토리지에서 조각 모음이 권장되지 않는다는 것입니다.

RAW 장치 매핑을 사용 중이거나 작업중인 LUN 인 RAID 세트에 직접 액세스 할 수있는 경우 조각 모음이 긍정적 인 영향을 줄 수 있지만 공유 RAID에서 "가상"LUN이 제공되는 경우 5 개 세트


훌륭한 기사. SAN 드라이브와 관련하여 적절합니다.
BradC 2016 년

7

이 질문과 답변의 여러 부분 :

Kevin이 지적했듯이 실제 파일 조각화는 Enterprise SAN 스토리지와 실제로 관련이 없으므로 추가 할 것은 없습니다. 실제로는 I / O 서브 시스템으로 이동하며 스캔을 수행 할 때 드라이브가 더 많은 I / O에서 스캔을 수행 할 때 더 순차적 인 I / O로 이동할 수있는 가능성이 있습니다. DAS의 경우 복잡한 슬라이스 앤 다이스 SAN의 경우에는 그렇지 않을 가능성이 큽니다.

파일 시스템 수준 조각 모음-SQL 종료시에만 수행하십시오. 온라인 데이터베이스 파일의 오픈 파일 조각 모음을 수행 한 적이 없기 때문에 여기에서 직접 문제가 발생하지는 않았지만 고객과 클라이언트로부터 이상한 부패 문제가 발생한다는 일화적인 증거를 많이 들었습니다. 일반적인 지혜는 SQL 온라인과 관련이 없습니다.

인덱스 조각화는 파일 조각화와 완전히 직교합니다. SQL Server는 파일 조각화에 대해 전혀 알지 못합니다. 실제 I / O 하위 시스템 지오메트리를 처리 할 수있을 정도로 너무 많은 가상화 계층이 있습니다. 그러나 인덱스 조각화는 SQL에 대한 모든 것을 알고 있습니다. 이미 언급 한 답변에서 나 자신을 너무 많이 반복하지 않으면 인덱스 조각화는 파일이 파일 시스템 수준에 어떻게 조각화되어 있는지에 관계없이 SQL이 효율적인 범위 스캔 판독을 수행하지 못하게합니다. 따라서 쿼리 성능이 저하되는 경우 인덱스 조각화를 반드시 완화해야합니다.

당신은하지 않습니다 이 파일 시스템 단편화 알아서하면되지만, 특정 순서로 다음을 수행하고 모든 인덱스를 다시 작성하고, 당신은 아마 갈거야 defragged 볼륨에 여러 파일을 성장하여 더 많은 파일 시스템 단편화의 원인 똑딱 거려 그래도 성능 문제가 발생합니까? 위에서 논의했듯이, 그것은 다음에 의존합니다 : -D

도움이 되었기를 바랍니다!


아, 내부 인덱스 조각화는 실제로 적절한 인덱스 범위 탐색 대신 전체 스캔을 선호하도록 옵티마이 저의 동작을 변경합니까?
BradC 2016 년

아니요. 옵티마이 저는 인덱스가 존재한다는 사실, 크기 및 열 값 분포 통계를 제외하고는 데이터가 디스크에 저장되는 방법을 알지 못합니다. 판독 엔진을 구동하고 스캔 대상의 논리적 조각화에 따라 개별 I / O 크기를 변경하는 것은 스토리지 엔진입니다.
Paul Randal

3

프로덕션 SQL 상자에서 실제 파일 조각화를 해결하는 가장 좋은 방법은 무엇입니까?

데이터베이스 파일에서 SYSINTERNALS 'contig를 실행합니다.

http://technet.microsoft.com/en-us/sysinternals/bb897428.aspx 참조


재미있어 보인다. Windows 조각 모음 API를 사용하기 때문에 SQL 서비스가 꺼져 있어야한다고 가정합니다. 아니면 서버 / 데이터베이스가 온라인 상태 일 때 실행됩니까?
BradC 2016 년

온라인 MSSQL Server 데이터베이스에서 성공적으로 사용했습니다. 그러나 트래픽이 적고 규모가 작은 데이터베이스 (10Gb 미만)
Vincent Buck

이것은 훌륭한 도구입니다! 다른 사람들이 언급했듯이 데이터베이스 응용 프로그램은 상당히 제한적이라고 생각하지만 다른 유형의 드라이브에는 좋아합니다. 분석 모드 -a는 작업이 진행되는 동안 안전합니다. 그래도 라이브 SQL Server에 속한 드라이브에 대해 안전하게 실행되지 않습니다.
Kendra

2

db의 크기를 적절하게 조정하고 SQL 서버를 종료하고 데이터베이스 파일을 다른 디스크 배열에 복사 한 다음 다시 복사하여 조각 모음을 수행하는 것이 좋습니다. 내 경험에서 Windows 조각 모음을 사용하는 것보다 훨씬 빠릅니다.


1

한 번 scsi 솔루션에서 물리 디스크 조각 모음을 시도했지만 성능이 거의 또는 전혀 향상되지 않았습니다. 내가 배운 교훈은 디스크 시스템으로 인해 성능이 저하되면 무작위 액세스를 사용하기 때문에 데이터 파일을 말하는 한 조각화와 관련이 없다는 것입니다.

인덱스가 조각 모음되고 통계가 업데이트되고 (매우 중요) 여전히 I / O가 병목 현상으로 나타나는 경우 물리적 조각화 이외의 다른 문제로 인해 어려움을 겪습니다. 드라이브의 80 % 이상을 사용 했습니까? 충분한 드라이브가 있습니까? 쿼리가 충분히 최적화 되었습니까? 클러스터 된 인덱스 조회가 뒤 따르는 많은 테이블 스캔 또는 더 많은 인덱스 탐색을 수행하고 있습니까? 쿼리 계획을보고 "통계 설정 io on"을 사용하여 쿼리에서 실제로 수행되는 작업을 찾으십시오. (많은 수의 논리적 또는 물리적 읽기를 찾으십시오)

내가 완전히 틀렸다면 알려주십시오.

하칸 윈터


아니, 넌 틀렸어 그러나 주 단위 분석 작업 동안 실행되는 150,000 개 이상의 고유 한 SQL 문 (과장하지는 않았지만 실제로는 과소 평가되지 않음)에 뛰어 들기 시작하는 것보다 (가능하면) 서버 전체에서 일부 개선을 시도하는 것이 조금 더 매력적입니다.
BradC

그런 상황이 있다면 Veritas I3가 환경을 분석하여 어떤 병목 현상이 발생했는지와 병목 현상을 일으키는 원인을 확인하는 것이 좋습니다. 베리타스 I3는 모든 진술과 진술 횟수 및 비용을 추적합니다. 훌륭한 소프트웨어입니다.
Hakan Winther

1

인덱스가 애플리케이션에 맞게 최적화되지 않았고 데이터베이스를 최적화 할 Veritas I3이없는 경우 다음과 같은 명령문을 사용하여 누락 된 인덱스를 찾을 수 있습니다.

       SELECT
      mid.statement,
      mid.equality_columns,
      mid.inequality_columns,
      mid.included_columns,
      migs.user_seeks,
      migs.user_scans,
      migs.last_user_seek,
      migs.avg_user_impact,
      user_scans,
      avg_total_user_cost,
      avg_total_user_cost * avg_user_impact * (user_seeks + user_scans) AS [weight]--, migs.*--, mid.*
   FROM
      sys.dm_db_missing_index_group_stats AS migs
      INNER JOIN sys.dm_db_missing_index_groups AS mig
         ON (migs.group_handle = mig.index_group_handle)
      INNER JOIN sys.dm_db_missing_index_details AS mid
         ON (mig.index_handle = mid.index_handle)
   ORDER BY
      avg_total_user_cost * avg_user_impact * (user_seeks + user_scans) DESC ;

또는 select 문에서 사용되지 않고 업데이트 / 삽입 성능을 저하시키는 인덱스를 찾기위한 다음과 같은 명령문 :

    CREATE PROCEDURE [ADMIN].[spIndexCostBenefit]
    @dbname [nvarchar](75)
WITH EXECUTE AS CALLER
AS
--set @dbname='Chess'
declare @dbid nvarchar(5)
declare @sql nvarchar(2000)
select @dbid = convert(nvarchar(5),db_id(@dbname))

set @sql=N'select ''object'' = t.name,i.name
        ,''user reads'' = iu.user_seeks + iu.user_scans + iu.user_lookups
        ,''system reads'' = iu.system_seeks + iu.system_scans + iu.system_lookups
        ,''user writes'' = iu.user_updates
        ,''system writes'' = iu.system_updates
from '+ @dbname + '.sys.dm_db_index_usage_stats iu
,' + @dbname + '.sys.indexes i
,' + @dbname + '.sys.tables t
where 
    iu.database_id = ' + @dbid + '
and iu.index_id=i.index_id
and iu.object_id=i.object_id
and iu.object_id=t.object_id
AND (iu.user_seeks + iu.user_scans + iu.user_lookups)<iu.user_updates
order by ''user reads'' desc'

exec sp_executesql @sql

set @sql=N'SELECT
   ''object'' = t.name,
   o.index_id,
   ''usage_reads'' = user_seeks + user_scans + user_lookups,
   ''operational_reads'' = range_scan_count + singleton_lookup_count,
   range_scan_count,
   singleton_lookup_count,
   ''usage writes'' = user_updates,
   ''operational_leaf_writes'' = leaf_insert_count + leaf_update_count + leaf_delete_count,
   leaf_insert_count,
   leaf_update_count,
   leaf_delete_count,
   ''operational_leaf_page_splits'' = leaf_allocation_count,
   ''operational_nonleaf_writes'' = nonleaf_insert_count + nonleaf_update_count + nonleaf_delete_count,
   ''operational_nonleaf_page_splits'' = nonleaf_allocation_count
FROM
   ' + @dbname + '.sys.dm_db_index_operational_stats(' + @dbid + ', NULL, NULL, NULL) o,
   ' + @dbname + '.sys.dm_db_index_usage_stats u,
    ' + @dbname + '.sys.tables t
WHERE
   u.object_id = o.object_id
   AND u.index_id = o.index_id
    and u.object_id=t.object_id
ORDER BY
   operational_reads DESC,
   operational_leaf_writes,
   operational_nonleaf_writes'

exec sp_executesql @sql

GO

프로덕션 환경에서 성능 문제를 분석 할 때 사용하는 다른 SQL 문이 있지만이 두 가지가 좋은 시작입니다.

(이 게시물은 약간의 주제이지만 색인 전략과 관련이 있기 때문에 관심이있을 것이라고 생각했습니다.)

하칸 윈터


훌륭한 스크립트, 나는 매우 비슷한 것을 가지고 있습니다. 불행하게도, 우리는 여전히 40 %의 SQL 2000 (문제의 서버 포함)이며, 이러한 "누락 된 인덱스"DMV와 동등한 것은 없습니다.
BradC 2016 년

그런 다음 Veritas I3을 살펴 보는 것이 좋습니다. 데이터베이스를 조정하는 데 사용할 수있는 우수한 제품이지만 저렴한 소프트웨어는 아닙니다.
Hakan Winther
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.