DMV를 사용하여 Azure Synapse Analytics 전용 SQL 풀 워크로드 모니터링
이 문서에서는 DMV(동적 관리 뷰)를 사용하여 전용 SQL 풀에서 쿼리 실행을 조사하는 작업을 비롯한 워크로드를 모니터링하는 방법을 설명합니다.
사용 권한
이 문서의 DMV를 쿼리하려면 VIEW DATABASE STATE 또는 CONTROL 권한이 필요합니다. 일반적으로 VIEW DATABASE STATE 권한 부여를 선호합니다. 훨씬 제한적이기 때문입니다.
GRANT VIEW DATABASE STATE TO myuser;
연결 모니터링
데이터 웨어하우스에 대한 모든 로그인이 sys.dm_pdw_exec_sessions에 기록됩니다. 이 DMV에는 마지막 10,000회의 로그인 정보가 포함됩니다. session_id
는 기본 키로, 각각의 새 로그인에 대해 순차적으로 할당됩니다.
-- Other Active Connections
SELECT * FROM sys.dm_pdw_exec_sessions where status <> 'Closed' and session_id <> session_id();
쿼리 실행 모니터링
SQL 풀에 실행되는 모든 쿼리는 sys.dm_pdw_exec_requests에 기록됩니다. 이 DMV에는 마지막으로 실행한 쿼리 10,000개가 포함됩니다. request_id
는 이 DMV의 기본 키인 request_id는 각 쿼리를 고유하게 식별합니다. request_id
는 각각의 새 쿼리에 대해 순차적으로 할당되며 쿼리 ID를 나타내는 QID가 접두사로 추가됩니다. 이 DMV에서 지정된 session_id
를 쿼리하면 지정된 로그온에 대한 모든 쿼리가 표시됩니다.
참고 항목
저장 프로시저는 여러 요청 ID를 사용합니다. 요청 ID는 순차적으로 할당됩니다.
특정 쿼리에 대한 쿼리 실행 계획 및 시간을 조사하기 위해 수행하는 단계는 다음과 같습니다.
1단계: 조사하려는 쿼리 식별
-- Monitor active queries
SELECT *
FROM sys.dm_pdw_exec_requests
WHERE status not in ('Completed','Failed','Cancelled')
AND session_id <> session_id()
ORDER BY submit_time DESC;
-- Find top 10 queries longest running queries
SELECT TOP 10 *
FROM sys.dm_pdw_exec_requests
ORDER BY total_elapsed_time DESC;
위의 쿼리 결과에서 조사할 쿼리의 요청 ID를 적어 둡니다 .
일시 중단 상태의 쿼리는 실행 중인 활성 쿼리 수가 많기 때문에 대기할 수 있습니다. 이러한 쿼리는 sys.dm_pdw_waits에도 나타납니다. 이 경우 UserConcurrencyResourceType과 같은 대기를 찾습니다. 동시성 제한에 대한 자세한 내용은 메모리 및 동시성 제한 또는 워크로드 관리를 위한 리소스 클래스를 참조하세요. 쿼리는 개체 잠금 등의 기타 이유로 인해 대기 상태일 수도 있습니다. 쿼리가 리소스를 대기 중인 경우 이 문서 뒷부분의 리소스를 대기 중인 쿼리 조사 를 참조하세요.
sys.dm_pdw_exec_requests 테이블에서 쿼리 조회를 간소화하려면 LABEL을 사용하여 sys.dm_pdw_exec_requests
뷰에서 조회할 수 있는 주석을 쿼리에 할당합니다.
-- Query with Label
SELECT *
FROM sys.tables
OPTION (LABEL = 'My Query')
;
-- Find a query with the Label 'My Query'
-- Use brackets when querying the label column, as it is a key word
SELECT *
FROM sys.dm_pdw_exec_requests
WHERE [label] = 'My Query';
2단계: 쿼리 계획 조사
요청 ID를 사용하여 sys.dm_pdw_request_steps에서 쿼리의 DSQL(분산된 SQL) 계획을 검색합니다.
-- Find the distributed query plan steps for a specific query.
-- Replace request_id with value from Step 1.
SELECT * FROM sys.dm_pdw_request_steps
WHERE request_id = 'QID####'
ORDER BY step_index;
DSQL 계획의 시간이 생각보다 오래 걸리는 경우 계획이 여러 DSQL 단계를 포함하여 복잡하거나 한 단계에 시간이 오래 걸리는 것일 수 있습니다. 계획에 많은 단계가 포함되어 있으며 여러 이동 작업이 수행되는 경우에는 테이블 분산을 최적화하여 데이터 이동을 줄일 수 있습니다. 테이블 분산 조항은 쿼리를 해결하기 위해 데이터를 이동해야 하는 이유를 설명합니다. 이 문서에서는 데이터 이동을 최소화하기 위한 몇 가지 배포 전략에 대해서도 설명합니다.
단일 단계에 대한 추가 세부 정보를 조사하려면 장기 실행 쿼리 단계의 operation_type
열을 검사하고 단계 인덱스를 확인합니다.
- SQL 작업(OnOperation, RemoteOperation, ReturnOperation)의 경우 3단계를 진행합니다.
- 데이터 이동 작업(ShuffleMoveOperation, BroadcastMoveOperation, TrimMoveOperation, PartitionMoveOperation, MoveOperation, CopyOperation)의 경우 4단계를 진행합니다.
3단계: 분산 데이터베이스에서 SQL 조사
요청 ID와 단계 인덱스를 사용하여 sys.dm_pdw_sql_requests에서 세부 정보를 검색합니다. 이 보기에는 모든 분산 데이터베이스에 대한 쿼리 단계의 실행 정보가 포함되어 있습니다.
-- Find the distribution run times for a SQL step.
-- Replace request_id and step_index with values from Step 1 and 3.
SELECT * FROM sys.dm_pdw_sql_requests
WHERE request_id = 'QID####' AND step_index = 2;
쿼리 단계가 실행되고 있으면 DBCC PDW_SHOWEXECUTIONPLAN을 사용하여 특정 분산에서 현재 실행 중인 단계에 대해 SQL Server 계획 캐시에서 SQL Server 예상 계획을 검색할 수 있습니다.
-- Find the SQL Server execution plan for a query running on a specific SQL pool or control node.
-- Replace distribution_id and spid with values from previous query.
DBCC PDW_SHOWEXECUTIONPLAN(1, 78);
4단계: 분산 데이터베이스에서 데이터 이동 조사
요청 ID 및 단계 인덱스를 사용하여 sys.dm_pdw_dms_workers에서 각 분산에 대해 실행 중인 데이터 이동 단계에 대한 정보를 검색합니다.
-- Find information about all the workers completing a Data Movement Step.
-- Replace request_id and step_index with values from Step 1 and 3.
SELECT * FROM sys.dm_pdw_dms_workers
WHERE request_id = 'QID####' AND step_index = 2;
total_elapsed_time
열을 검사하여 특정 배포에서 데이터 이동 시간이 다른 배포보다 훨씬 오래 걸리는지 확인합니다.- 장기 실행 배포의 경우
rows_processed
열을 검사하여 해당 배포에서 이동되는 행 수가 다른 배포보다 훨씬 큰지 확인합니다. 그렇다면 이 결과는 기본 데이터의 왜곡을 나타낼 수 있습니다. 데이터 기울이기의 한 가지 원인은 여러 NULL 값이 있는 열에 배포하기 때문입니다(행이 모두 동일한 배포에 배치됨). 이 유형의 열에 대한 배포를 방지하거나 가능한 경우 Null을 제거하도록 쿼리를 필터링하여 쿼리 속도 저하를 방지합니다.
쿼리가 실행되고 있으면 DBCC PDW_SHOWEXECUTIONPLAN을 사용하여 특정 배포 내에서 현재 실행 중인 SQL 단계에 대한 SQL Server 계획 캐시에서 SQL Server 예상 계획을 회수할 수 있습니다.
-- Find the SQL Server estimated plan for a query running on a specific SQL pool Compute or control node.
-- Replace distribution_id and spid with values from previous query.
DBCC PDW_SHOWEXECUTIONPLAN(55, 238);
대기 중인 쿼리 모니터링
쿼리가 리소스를 대기하는 중이어서 진행되고 있지 않은 경우, 쿼리가 대기 중인 모든 리소스를 표시하는 쿼리는 다음과 같습니다.
-- Find queries
-- Replace request_id with value from Step 1.
SELECT waits.session_id,
waits.request_id,
requests.command,
requests.status,
requests.start_time,
waits.type,
waits.state,
waits.object_type,
waits.object_name
FROM sys.dm_pdw_waits waits
JOIN sys.dm_pdw_exec_requests requests
ON waits.request_id=requests.request_id
WHERE waits.request_id = 'QID####'
ORDER BY waits.object_name, waits.object_type, waits.state;
쿼리가 적극적으로 다른 쿼리의 리소스를 대기 중인 경우 상태는 AcquireResources입니다. 쿼리가 필요한 리소스를 모두 가지고 있으면 상태는 Granted입니다.
tempdb 모니터링
tempdb
데이터베이스는 쿼리를 실행하는 동안 중간 결과를 저장하는 데 사용됩니다. tempdb
데이터베이스의 사용률이 높으면 쿼리 성능이 저하될 수 있습니다. 구성된 모든 DW100c에 대해 399GB의 tempdb
공간이 할당됩니다(DW1000c에 3.99TB의 tempdb
공간이 있음). 다음은 tempdb
사용을 모니터링하고 쿼리에서 tempdb
사용을 줄이는 데 유용한 팁입니다.
뷰를 사용하여 tempdb 모니터링
tempdb
사용량을 모니터링하려면 먼저 Microsoft Toolkit for SQL 풀에서 microsoft.vw_sql_requests 뷰를 설치합니다. 그러면 다음 쿼리를 실행하여 실행된 모든 쿼리에 대한 노드당 tempdb
사용량을 확인할 수 있습니다.
-- Monitor tempdb
SELECT
sr.request_id,
ssu.session_id,
ssu.pdw_node_id,
sr.command,
sr.total_elapsed_time,
exs.login_name AS 'LoginName',
DB_NAME(ssu.database_id) AS 'DatabaseName',
(es.memory_usage * 8) AS 'MemoryUsage (in KB)',
(ssu.user_objects_alloc_page_count * 8) AS 'Space Allocated For User Objects (in KB)',
(ssu.user_objects_dealloc_page_count * 8) AS 'Space Deallocated For User Objects (in KB)',
(ssu.internal_objects_alloc_page_count * 8) AS 'Space Allocated For Internal Objects (in KB)',
(ssu.internal_objects_dealloc_page_count * 8) AS 'Space Deallocated For Internal Objects (in KB)',
CASE es.is_user_process
WHEN 1 THEN 'User Session'
WHEN 0 THEN 'System Session'
END AS 'SessionType',
es.row_count AS 'RowCount'
FROM sys.dm_pdw_nodes_db_session_space_usage AS ssu
INNER JOIN sys.dm_pdw_nodes_exec_sessions AS es ON ssu.session_id = es.session_id AND ssu.pdw_node_id = es.pdw_node_id
INNER JOIN sys.dm_pdw_nodes_exec_connections AS er ON ssu.session_id = er.session_id AND ssu.pdw_node_id = er.pdw_node_id
INNER JOIN microsoft.vw_sql_requests AS sr ON ssu.session_id = sr.spid AND ssu.pdw_node_id = sr.pdw_node_id
LEFT JOIN sys.dm_pdw_exec_requests exr on exr.request_id = sr.request_id
LEFT JOIN sys.dm_pdw_exec_sessions exs on exr.session_id = exs.session_id
WHERE DB_NAME(ssu.database_id) = 'tempdb'
AND es.session_id <> @@SPID
AND es.login_name <> 'sa'
ORDER BY sr.request_id;
참고 항목
데이터 이동은 tempdb
를 사용합니다. 데이터 이동 중에 tempdb
의 사용을 줄이려면 테이블이 데이터를 균등하게 분산하는 분산 전략을 사용하고 있는지 확인합니다.
Azure Synapse SQL 배포 관리자를 사용하여 워크로드에 적합한 배포 방법에 대한 권장 사항을 가져오세요.
T-SQL 쿼리를 사용하여 tempdb
를 모니터링하려면 Azure Synapse Toolkit을 사용합니다.
많은 양의 메모리를 사용하는 쿼리가 있거나 tempdb
할당과 관련된 오류 메시지를 받은 경우 최종 데이터 이동 작업에서 실패한 실행 중인 매우 큰 CREATE TABLE AS SELECT(CTAS) 또는 INSERT SELECT 문 때문일 수 있습니다. 이는 일반적으로 분산 쿼리 계획에서 최종 INSERT SELECT 바로 전에 ShuffleMove 작업으로 식별될 수 있습니다. sys.dm_pdw_request_steps를 사용하여 ShuffleMove 작업을 모니터링합니다.
가장 일반적인 완화 방법은 데이터 볼륨이 100DWUc당 399GB tempdb
제한을 초과하지 않도록 CTAS 또는 INSERT SELECT 문을 여러 로드 문으로 나누는 것입니다. 클러스터 크기를 더 큰 크기로 스케일링하여 tempdb
공간을 늘릴 수도 있습니다.
CTAS 및 INSERT SELECT 문 외에도 메모리 부족 상태에서 실행되는 복잡한 쿼리는 tempdb
로 분할되어 쿼리가 실패할 수 있습니다. tempdb
로 넘치지 않도록 더 큰 리소스 클래스를 사용하여 실행하는 것이 좋습니다.
메모리 모니터링
메모리는 성능 저하 및 메모리 부족 문제의 근본 원인일 수 있습니다. SQL Server 메모리 사용량이 쿼리 실행 중 한계에 도달한 것을 발견한 경우 데이터 웨어하우스를 확장하는 것이 좋습니다.
다음 쿼리는 노드당 SQL Server 메모리 사용량 및 메모리 부족을 반환합니다.
-- Memory consumption
SELECT
pc1.cntr_value as Curr_Mem_KB,
pc1.cntr_value/1024.0 as Curr_Mem_MB,
(pc1.cntr_value/1048576.0) as Curr_Mem_GB,
pc2.cntr_value as Max_Mem_KB,
pc2.cntr_value/1024.0 as Max_Mem_MB,
(pc2.cntr_value/1048576.0) as Max_Mem_GB,
pc1.cntr_value * 100.0/pc2.cntr_value AS Memory_Utilization_Percentage,
pc1.pdw_node_id
FROM
-- pc1: current memory
sys.dm_pdw_nodes_os_performance_counters AS pc1
-- pc2: total memory allowed for this SQL instance
JOIN sys.dm_pdw_nodes_os_performance_counters AS pc2
ON pc1.object_name = pc2.object_name AND pc1.pdw_node_id = pc2.pdw_node_id
WHERE
pc1.counter_name = 'Total Server Memory (KB)'
AND pc2.counter_name = 'Target Server Memory (KB)'
트랜잭션 로그 크기 모니터링
다음 쿼리는 각 배포에서 트랜잭션 로그 크기를 반환합니다. 로그 파일 중 하나가 160GB에 도달하는 경우 인스턴스를 확장하거나 트랜잭션 크기를 제한해야 합니다.
-- Transaction log size
SELECT
instance_name as distribution_db,
cntr_value*1.0/1048576 as log_file_size_used_GB,
pdw_node_id
FROM sys.dm_pdw_nodes_os_performance_counters
WHERE
instance_name like 'Distribution_%'
AND counter_name = 'Log File(s) Used Size (KB)'
트랜잭션 로그 롤백 모니터링
쿼리가 실패하거나 진행하는 데 시간이 오래 걸리는 경우 트랜잭션 롤백이 있는지 확인하고 모니터링할 수 있습니다.
-- Monitor rollback
SELECT
SUM(CASE WHEN t.database_transaction_next_undo_lsn IS NOT NULL THEN 1 ELSE 0 END),
t.pdw_node_id,
nod.[type]
FROM sys.dm_pdw_nodes_tran_database_transactions t
JOIN sys.dm_pdw_nodes nod ON t.pdw_node_id = nod.pdw_node_id
GROUP BY t.pdw_node_id, nod.[type]
PolyBase 부하 모니터링
다음 쿼리를 통해 예상되는 로드 진행률을 확인할 수 있습니다. 이 쿼리는 현재 처리 중인 파일만 표시합니다.
-- To track bytes and files
SELECT
r.command,
s.request_id,
r.status,
count(distinct input_name) as nbr_files,
sum(s.bytes_processed)/1024/1024/1024 as gb_processed
FROM
sys.dm_pdw_exec_requests r
inner join sys.dm_pdw_dms_external_work s
on r.request_id = s.request_id
GROUP BY
r.command,
s.request_id,
r.status
ORDER BY
nbr_files desc,
gb_processed desc;
쿼리 차단 모니터링
다음 쿼리는 환경에서 차단된 상위 500개의 쿼리를 제공합니다.
--Collect the top blocking
SELECT
TOP 500 waiting.request_id AS WaitingRequestId,
waiting.object_type AS LockRequestType,
waiting.object_name AS ObjectLockRequestName,
waiting.request_time AS ObjectLockRequestTime,
blocking.session_id AS BlockingSessionId,
blocking.request_id AS BlockingRequestId
FROM
sys.dm_pdw_waits waiting
INNER JOIN sys.dm_pdw_waits blocking
ON waiting.object_type = blocking.object_type
AND waiting.object_name = blocking.object_name
WHERE
waiting.state = 'Queued'
AND blocking.state = 'Granted'
ORDER BY
ObjectLockRequestTime ASC;
대기 중 및 차단 쿼리에서 쿼리 텍스트 검색
다음 쿼리는 쉽게 문제를 해결하기 위해 대기 및 차단 쿼리에 대한 쿼리 텍스트 및 식별자를 제공합니다.
-- To retrieve query text from waiting and blocking queries
SELECT waiting.session_id AS WaitingSessionId,
waiting.request_id AS WaitingRequestId,
COALESCE(waiting_exec_request.command,waiting_exec_request.command2) AS WaitingExecRequestText,
waiting.object_name AS Waiting_Object_Name,
waiting.object_type AS Waiting_Object_Type,
blocking.session_id AS BlockingSessionId,
blocking.request_id AS BlockingRequestId,
COALESCE(blocking_exec_request.command,blocking_exec_request.command2) AS BlockingExecRequestText,
blocking.object_name AS Blocking_Object_Name,
blocking.object_type AS Blocking_Object_Type,
waiting.type AS Lock_Type,
waiting.request_time AS Lock_Request_Time,
datediff(ms, waiting.request_time, getdate())/1000.0 AS Blocking_Time_sec
FROM sys.dm_pdw_waits waiting
INNER JOIN sys.dm_pdw_waits blocking
ON waiting.object_type = blocking.object_type
AND waiting.object_name = blocking.object_name
INNER JOIN sys.dm_pdw_exec_requests blocking_exec_request
ON blocking.request_id = blocking_exec_request.request_id
INNER JOIN sys.dm_pdw_exec_requests waiting_exec_request
ON waiting.request_id = waiting_exec_request.request_id
WHERE waiting.state = 'Queued'
AND blocking.state = 'Granted'
ORDER BY Lock_Request_Time DESC;
다음 단계
- DMV에 대한 자세한 내용은 시스템 뷰를 참조하세요.