Megosztás a következőn keresztül:


Felügyelt Microsoft Azure SQL-példány teljesítményének monitorozása dinamikus felügyeleti nézetek használatával

A következőre vonatkozik: Felügyelt Azure SQL-példány

A Felügyelt Microsoft Azure SQL-példány lehetővé teszi a dinamikus felügyeleti nézetek (DMV-k) egy részhalmazát a teljesítményproblémák diagnosztizálásához, amelyeket blokkolt vagy hosszan futó lekérdezések, erőforrás szűk keresztmetszetek, gyenge lekérdezési tervek stb. okozhatnak. Ez a cikk a gyakori teljesítményproblémák dinamikus felügyeleti nézetek használatával történő észleléséről nyújt tájékoztatást.

Ez a cikk a felügyelt Azure SQL-példányról szól, lásd még a Microsoft Azure SQL Database teljesítményének dinamikus felügyeleti nézetek használatával történő monitorozását.

Jogosultságok

A felügyelt Azure SQL-példányban a dinamikus felügyeleti nézet lekérdezéséhez VIEW Standard kiadás RVER STATE-engedélyekre van szükség.

GRANT VIEW SERVER STATE TO database_user;

Az SQL Server egy példányában és a felügyelt Azure SQL-példányban a dinamikus felügyeleti nézetek a kiszolgáló állapotadatait adják vissza.

A CPU-teljesítmény problémáinak azonosítása

Ha a processzorhasználat hosszabb ideig 80% felett van, fontolja meg a következő hibaelhárítási lépéseket:

A cpu-probléma most jelentkezik

Ha a probléma jelenleg is fennáll, két lehetséges forgatókönyv lehetséges:

Sok egyedi lekérdezés, amelyek halmozottan magas processzorhasználatot használnak fel

A leggyakoribb lekérdezési kivonatok azonosításához használja a következő lekérdezést:

PRINT '-- top 10 Active CPU Consuming Queries (aggregated)--';
SELECT TOP 10 GETDATE() runtime, *
FROM (SELECT query_stats.query_hash, SUM(query_stats.cpu_time) 'Total_Request_Cpu_Time_Ms', SUM(logical_reads) 'Total_Request_Logical_Reads', MIN(start_time) 'Earliest_Request_start_Time', COUNT(*) 'Number_Of_Requests', SUBSTRING(REPLACE(REPLACE(MIN(query_stats.statement_text), CHAR(10), ' '), CHAR(13), ' '), 1, 256) AS "Statement_Text"
    FROM (SELECT req.*, SUBSTRING(ST.text, (req.statement_start_offset / 2)+1, ((CASE statement_end_offset WHEN -1 THEN DATALENGTH(ST.text)ELSE req.statement_end_offset END-req.statement_start_offset)/ 2)+1) AS statement_text
          FROM sys.dm_exec_requests AS req
                CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) AS ST ) AS query_stats
    GROUP BY query_hash) AS t
ORDER BY Total_Request_Cpu_Time_Ms DESC;

Jelenleg is futnak hosszan futó, CPU-t használó lekérdezések

A következő lekérdezésekkel azonosíthatja ezeket a lekérdezéseket:

PRINT '--top 10 Active CPU Consuming Queries by sessions--';
SELECT TOP 10 req.session_id, req.start_time, cpu_time 'cpu_time_ms', OBJECT_NAME(ST.objectid, ST.dbid) 'ObjectName', SUBSTRING(REPLACE(REPLACE(SUBSTRING(ST.text, (req.statement_start_offset / 2)+1, ((CASE statement_end_offset WHEN -1 THEN DATALENGTH(ST.text)ELSE req.statement_end_offset END-req.statement_start_offset)/ 2)+1), CHAR(10), ' '), CHAR(13), ' '), 1, 512) AS statement_text
FROM sys.dm_exec_requests AS req
    CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) AS ST
ORDER BY cpu_time DESC;
GO

A processzorral kapcsolatos probléma a múltban fordult elő

Ha a probléma a múltban történt, és alapvető okelemzést szeretne végezni, használja a Lekérdezéstárat. Az adatbázis-hozzáféréssel rendelkező felhasználók a T-SQL használatával kérdezhetik le a lekérdezéstár adatait. A Lekérdezéstár alapértelmezett konfigurációi 1 órás részletességet használnak. Az alábbi lekérdezéssel megtekintheti a magas processzorhasználatú lekérdezések tevékenységeit. Ez a lekérdezés a 15 processzort használó lekérdezést adja vissza. Ne felejtse el módosítani rsi.start_time >= DATEADD(hour, -2, GETUTCDATE():

-- Top 15 CPU consuming queries by query hash
-- note that a query  hash can have many query id if not parameterized or not parameterized properly
-- it grabs a sample query text by min
WITH AggregatedCPU AS (SELECT q.query_hash, SUM(count_executions * avg_cpu_time / 1000.0) AS total_cpu_millisec, SUM(count_executions * avg_cpu_time / 1000.0)/ SUM(count_executions) AS avg_cpu_millisec, MAX(rs.max_cpu_time / 1000.00) AS max_cpu_millisec, MAX(max_logical_io_reads) max_logical_reads, COUNT(DISTINCT p.plan_id) AS number_of_distinct_plans, COUNT(DISTINCT p.query_id) AS number_of_distinct_query_ids, SUM(CASE WHEN rs.execution_type_desc='Aborted' THEN count_executions ELSE 0 END) AS Aborted_Execution_Count, SUM(CASE WHEN rs.execution_type_desc='Regular' THEN count_executions ELSE 0 END) AS Regular_Execution_Count, SUM(CASE WHEN rs.execution_type_desc='Exception' THEN count_executions ELSE 0 END) AS Exception_Execution_Count, SUM(count_executions) AS total_executions, MIN(qt.query_sql_text) AS sampled_query_text
                       FROM sys.query_store_query_text AS qt
                            JOIN sys.query_store_query AS q ON qt.query_text_id=q.query_text_id
                            JOIN sys.query_store_plan AS p ON q.query_id=p.query_id
                            JOIN sys.query_store_runtime_stats AS rs ON rs.plan_id=p.plan_id
                            JOIN sys.query_store_runtime_stats_interval AS rsi ON rsi.runtime_stats_interval_id=rs.runtime_stats_interval_id
                       WHERE rs.execution_type_desc IN ('Regular', 'Aborted', 'Exception')AND rsi.start_time>=DATEADD(HOUR, -2, GETUTCDATE())
                       GROUP BY q.query_hash), OrderedCPU AS (SELECT query_hash, total_cpu_millisec, avg_cpu_millisec, max_cpu_millisec, max_logical_reads, number_of_distinct_plans, number_of_distinct_query_ids, total_executions, Aborted_Execution_Count, Regular_Execution_Count, Exception_Execution_Count, sampled_query_text, ROW_NUMBER() OVER (ORDER BY total_cpu_millisec DESC, query_hash ASC) AS RN
                                                              FROM AggregatedCPU)
SELECT OD.query_hash, OD.total_cpu_millisec, OD.avg_cpu_millisec, OD.max_cpu_millisec, OD.max_logical_reads, OD.number_of_distinct_plans, OD.number_of_distinct_query_ids, OD.total_executions, OD.Aborted_Execution_Count, OD.Regular_Execution_Count, OD.Exception_Execution_Count, OD.sampled_query_text, OD.RN
FROM OrderedCPU AS OD
WHERE OD.RN<=15
ORDER BY total_cpu_millisec DESC;

Miután azonosította a problémás lekérdezéseket, ideje hangolni ezeket a lekérdezéseket a processzorhasználat csökkentése érdekében. Ha nincs ideje a lekérdezések finomhangolására, a probléma megoldásához a felügyelt példány SLO-ját is frissítheti.

I/O-teljesítménnyel kapcsolatos problémák azonosítása

Az I/O-teljesítménnyel kapcsolatos problémák azonosítása során az I/O-problémákhoz tartozó legfontosabb várakozási típusok a következők:

  • PAGEIOLATCH_*

    Adatfájl I/O-problémái esetén (beleértve a PAGEIOLATCH_SH, PAGEIOLATCH_EX, PAGEIOLATCH_UP). Ha a várakozási típus neve IO-t használ, az egy IO-problémára mutat. Ha nincs I/O az oldal retesz várakozási nevére, az egy másik típusú problémára mutat (például tempdb versengés).

  • WRITE_LOG

    Tranzakciónapló I/O-problémái esetén.

Ha az I/O-probléma jelenleg is fennáll

A sys.dm_exec_requests vagy a sys.dm_os_waiting_tasks használatával megtekintheti az és wait_timea wait_type .

A 2. lehetőségnél a következő lekérdezést használhatja a Lekérdezéstárban a pufferrel kapcsolatos I/O-khoz a nyomon követett tevékenység utolsó két órájának megtekintéséhez:

-- top queries that waited on buffer
-- note these are finished queries
WITH Aggregated AS (SELECT q.query_hash, SUM(total_query_wait_time_ms) total_wait_time_ms, SUM(total_query_wait_time_ms / avg_query_wait_time_ms) AS total_executions, MIN(qt.query_sql_text) AS sampled_query_text, MIN(wait_category_desc) AS wait_category_desc
                    FROM sys.query_store_query_text AS qt
                         JOIN sys.query_store_query AS q ON qt.query_text_id=q.query_text_id
                         JOIN sys.query_store_plan AS p ON q.query_id=p.query_id
                         JOIN sys.query_store_wait_stats AS waits ON waits.plan_id=p.plan_id
                         JOIN sys.query_store_runtime_stats_interval AS rsi ON rsi.runtime_stats_interval_id=waits.runtime_stats_interval_id
                    WHERE wait_category_desc='Buffer IO' AND rsi.start_time>=DATEADD(HOUR, -2, GETUTCDATE())
                    GROUP BY q.query_hash), Ordered AS (SELECT query_hash, total_executions, total_wait_time_ms, sampled_query_text, wait_category_desc, ROW_NUMBER() OVER (ORDER BY total_wait_time_ms DESC, query_hash ASC) AS RN
                                                        FROM Aggregated)
SELECT OD.query_hash, OD.total_executions, OD.total_wait_time_ms, OD.sampled_query_text, OD.wait_category_desc, OD.RN
FROM Ordered AS OD
WHERE OD.RN<=15
ORDER BY total_wait_time_ms DESC;
GO

A teljes napló IO megtekintése a WRITELOG-várakozásokhoz

Ha a várakozás típusa az WRITELOG, a következő lekérdezéssel megtekintheti a teljes napló IO-t utasítás szerint:

-- Top transaction log consumers
-- Adjust the time window by changing
-- rsi.start_time >= DATEADD(hour, -2, GETUTCDATE())
WITH AggregatedLogUsed
AS (SELECT q.query_hash,
           SUM(count_executions * avg_cpu_time / 1000.0) AS total_cpu_millisec,
           SUM(count_executions * avg_cpu_time / 1000.0) / SUM(count_executions) AS avg_cpu_millisec,
           SUM(count_executions * avg_log_bytes_used) AS total_log_bytes_used,
           MAX(rs.max_cpu_time / 1000.00) AS max_cpu_millisec,
           MAX(max_logical_io_reads) max_logical_reads,
           COUNT(DISTINCT p.plan_id) AS number_of_distinct_plans,
           COUNT(DISTINCT p.query_id) AS number_of_distinct_query_ids,
           SUM(   CASE
                      WHEN rs.execution_type_desc = 'Aborted' THEN
                          count_executions
                      ELSE
                          0
                  END
              ) AS Aborted_Execution_Count,
           SUM(   CASE
                      WHEN rs.execution_type_desc = 'Regular' THEN
                          count_executions
                      ELSE
                          0
                  END
              ) AS Regular_Execution_Count,
           SUM(   CASE
                      WHEN rs.execution_type_desc = 'Exception' THEN
                          count_executions
                      ELSE
                          0
                  END
              ) AS Exception_Execution_Count,
           SUM(count_executions) AS total_executions,
           MIN(qt.query_sql_text) AS sampled_query_text
    FROM sys.query_store_query_text AS qt
        JOIN sys.query_store_query AS q
            ON qt.query_text_id = q.query_text_id
        JOIN sys.query_store_plan AS p
            ON q.query_id = p.query_id
        JOIN sys.query_store_runtime_stats AS rs
            ON rs.plan_id = p.plan_id
        JOIN sys.query_store_runtime_stats_interval AS rsi
            ON rsi.runtime_stats_interval_id = rs.runtime_stats_interval_id
    WHERE rs.execution_type_desc IN ( 'Regular', 'Aborted', 'Exception' )
          AND rsi.start_time >= DATEADD(HOUR, -2, GETUTCDATE())
    GROUP BY q.query_hash),
     OrderedLogUsed
AS (SELECT query_hash,
           total_log_bytes_used,
           number_of_distinct_plans,
           number_of_distinct_query_ids,
           total_executions,
           Aborted_Execution_Count,
           Regular_Execution_Count,
           Exception_Execution_Count,
           sampled_query_text,
           ROW_NUMBER() OVER (ORDER BY total_log_bytes_used DESC, query_hash ASC) AS RN
    FROM AggregatedLogUsed)
SELECT OD.total_log_bytes_used,
       OD.number_of_distinct_plans,
       OD.number_of_distinct_query_ids,
       OD.total_executions,
       OD.Aborted_Execution_Count,
       OD.Regular_Execution_Count,
       OD.Exception_Execution_Count,
       OD.sampled_query_text,
       OD.RN
FROM OrderedLogUsed AS OD
WHERE OD.RN <= 15
ORDER BY total_log_bytes_used DESC;
GO

Teljesítményproblémák azonosítása tempdb

Az I/O teljesítményproblémáinak azonosításakor a problémákhoz tempdb társított leggyakoribb várakozási típusok a PAGELATCH_* (nem PAGEIOLATCH_*). A PAGELATCH_* várakozások azonban nem mindig jelentik azt, hogy versengés van tempdb . A várakozás annak a jele is lehet, hogy a felhasználó és az objektum adatlapjai között van versengés, mivel egyszerre több kérés célozza ugyanazt az adatlapot. A versengés további megerősítéséhez tempdb használja a sys.dm_exec_requests annak megerősítését, hogy a wait_resource érték azzal kezdődik2:x:y, hogy a 2 tempdb az adatbázis azonosítója, x a fájlazonosító, és y az oldalazonosító.

A versengés esetében tempdb gyakori módszer a támaszkodó alkalmazáskód csökkentése vagy átírása tempdb. Gyakori tempdb használati területek a következők:

  • Ideiglenes táblák
  • Ideiglenes változók
  • Ideiglenes értékű paraméterek
  • Verziótár használata (hosszú ideig futó tranzakciókhoz társítva)
  • Lekérdezések, amelyek lekérdezési terve rendezéseket, kivonatillesztéseket és sorba állításokat használ.

Táblaváltozókat és ideiglenes táblákat használó leggyakoribb lekérdezések

A következő lekérdezés használatával azonosíthatja a táblaváltozókat és ideiglenes táblákat használó leggyakoribb lekérdezéseket:

SELECT plan_handle, execution_count, query_plan
INTO #tmpPlan
FROM sys.dm_exec_query_stats
     CROSS APPLY sys.dm_exec_query_plan(plan_handle);
GO

WITH XMLNAMESPACES('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
SELECT plan_handle, stmt.stmt_details.value('@Database', 'varchar(max)') 'Database', stmt.stmt_details.value('@Schema', 'varchar(max)') 'Schema', stmt.stmt_details.value('@Table', 'varchar(max)') 'table'
INTO #tmp2
FROM(SELECT CAST(query_plan AS XML) sqlplan, plan_handle FROM #tmpPlan) AS p
    CROSS APPLY sqlplan.nodes('//sp:Object') AS stmt(stmt_details);
GO

SELECT t.plan_handle, [Database], [Schema], [table], execution_count
FROM(SELECT DISTINCT plan_handle, [Database], [Schema], [table]
     FROM #tmp2
     WHERE [table] LIKE '%@%' OR [table] LIKE '%#%') AS t
    JOIN #tmpPlan AS t2 ON t.plan_handle=t2.plan_handle;

Hosszú ideig futó tranzakciók azonosítása

A hosszú ideig futó tranzakciók azonosításához használja az alábbi lekérdezést. A hosszan futó tranzakciók megakadályozzák a verziótár törlését.

SELECT DB_NAME(dtr.database_id) 'database_name',
       sess.session_id,
       atr.name AS 'tran_name',
       atr.transaction_id,
       transaction_type,
       transaction_begin_time,
       database_transaction_begin_time, 
       transaction_state,
       is_user_transaction,
       sess.open_transaction_count,
       TRIM(REPLACE(
                REPLACE(
                            SUBSTRING(
                                        SUBSTRING(
                                                    txt.text,
                                                    (req.statement_start_offset / 2) + 1,
                                                    ((CASE req.statement_end_offset
                                                            WHEN -1 THEN
                                                                DATALENGTH(txt.text)
                                                            ELSE
                                                                req.statement_end_offset
                                                        END - req.statement_start_offset
                                                    ) / 2
                                                    ) + 1
                                                ),
                                        1,
                                        1000
                                    ),
                            CHAR(10),
                            ' '
                        ),
                CHAR(13),
                ' '
            )
            ) Running_stmt_text,
       recenttxt.text 'MostRecentSQLText'
FROM sys.dm_tran_active_transactions AS atr
    INNER JOIN sys.dm_tran_database_transactions AS dtr
        ON dtr.transaction_id = atr.transaction_id
    LEFT JOIN sys.dm_tran_session_transactions AS sess
        ON sess.transaction_id = atr.transaction_id
    LEFT JOIN sys.dm_exec_requests AS req
        ON req.session_id = sess.session_id
           AND req.transaction_id = sess.transaction_id
    LEFT JOIN sys.dm_exec_connections AS conn
        ON sess.session_id = conn.session_id
    OUTER APPLY sys.dm_exec_sql_text(req.sql_handle) AS txt
    OUTER APPLY sys.dm_exec_sql_text(conn.most_recent_sql_handle) AS recenttxt
WHERE atr.transaction_type != 2
      AND sess.session_id != @@spid
ORDER BY start_time ASC;

Memóriahasználati várakozási teljesítménnyel kapcsolatos problémák azonosítása

Ha a legnagyobb várakozási típus, RESOURCE_SEMAHPORE és nincs magas processzorhasználati problémája, előfordulhat, hogy memóriakivételi várakozási problémát tapasztal.

Annak meghatározása, hogy a RESOURCE_SEMAHPORE várakozás a legnagyobb várakozás-e

A következő lekérdezéssel megállapíthatja, hogy a RESOURCE_SEMAHPORE várakozás a legmagasabb várakozási idő-e

SELECT wait_type,
       SUM(wait_time) AS total_wait_time_ms
FROM sys.dm_exec_requests AS req
    JOIN sys.dm_exec_sessions AS sess
        ON req.session_id = sess.session_id
WHERE is_user_process = 1
GROUP BY wait_type
ORDER BY SUM(wait_time) DESC;

Nagy memóriaigényű utasítások azonosítása

Ha memóriahiány miatti hibákat tapasztal, tekintse át a sys.dm_os_out_of_memory_events dokumentációját.

A nagy memóriaigényű utasítások azonosításához használja a következő lekérdezést:

SELECT IDENTITY(INT, 1, 1) rowId,
    CAST(query_plan AS XML) query_plan,
    p.query_id
INTO #tmp
FROM sys.query_store_plan AS p
    JOIN sys.query_store_runtime_stats AS r
        ON p.plan_id = r.plan_id
    JOIN sys.query_store_runtime_stats_interval AS i
        ON r.runtime_stats_interval_id = i.runtime_stats_interval_id
WHERE start_time > '2018-10-11 14:00:00.0000000'
      AND end_time < '2018-10-17 20:00:00.0000000';
GO
;WITH cte
AS (SELECT query_id,
        query_plan,
        m.c.value('@SerialDesiredMemory', 'INT') AS SerialDesiredMemory
    FROM #tmp AS t
        CROSS APPLY t.query_plan.nodes('//*:MemoryGrantInfo[@SerialDesiredMemory[. > 0]]') AS m(c) )
SELECT TOP 50
    cte.query_id,
    t.query_sql_text,
    cte.query_plan,
    CAST(SerialDesiredMemory / 1024. AS DECIMAL(10, 2)) SerialDesiredMemory_MB
FROM cte
    JOIN sys.query_store_query AS q
        ON cte.query_id = q.query_id
    JOIN sys.query_store_query_text AS t
        ON q.query_text_id = t.query_text_id
ORDER BY SerialDesiredMemory DESC;

A memória-vissza nem térítendők azonosítása

Az alábbi lekérdezés segítségével azonosíthatja a 10 legfontosabb aktív memória-támogatást:

SELECT TOP 10
    CONVERT(VARCHAR(30), GETDATE(), 121) AS runtime,
       r.session_id,
       r.blocking_session_id,
       r.cpu_time,
       r.total_elapsed_time,
       r.reads,
       r.writes,
       r.logical_reads,
       r.row_count,
       wait_time,
       wait_type,
       r.command,
       OBJECT_NAME(txt.objectid, txt.dbid) 'Object_Name',
       TRIM(REPLACE(
                REPLACE(
                            SUBSTRING(
                                        SUBSTRING(
                                                    text,
                                                    (r.statement_start_offset / 2) + 1,
                                                    ((CASE r.statement_end_offset
                                                            WHEN -1 THEN
                                                                DATALENGTH(text)
                                                            ELSE
                                                                r.statement_end_offset
                                                        END - r.statement_start_offset
                                                    ) / 2
                                                    ) + 1
                                                ),
                                        1,
                                        1000
                                    ),
                            CHAR(10),
                            ' '
                        ),
                CHAR(13),
                ' '
            )
            ) stmt_text,
       mg.dop,                                               --Degree of parallelism
       mg.request_time,                                      --Date and time when this query requested the memory grant.
       mg.grant_time,                                        --NULL means memory has not been granted
       mg.requested_memory_kb / 1024.0 requested_memory_mb,  --Total requested amount of memory in megabytes
       mg.granted_memory_kb / 1024.0 AS granted_memory_mb,   --Total amount of memory actually granted in megabytes. NULL if not granted
       mg.required_memory_kb / 1024.0 AS required_memory_mb, --Minimum memory required to run this query in megabytes.
       max_used_memory_kb / 1024.0 AS max_used_memory_mb,
       mg.query_cost,                                        --Estimated query cost.
       mg.timeout_sec,                                       --Time-out in seconds before this query gives up the memory grant request.
       mg.resource_semaphore_id,                             --Non-unique ID of the resource semaphore on which this query is waiting.
       mg.wait_time_ms,                                      --Wait time in milliseconds. NULL if the memory is already granted.
       CASE mg.is_next_candidate --Is this process the next candidate for a memory grant
           WHEN 1 THEN
               'Yes'
           WHEN 0 THEN
               'No'
           ELSE
               'Memory has been granted'
       END AS 'Next Candidate for Memory Grant',
       qp.query_plan
FROM sys.dm_exec_requests AS r
    JOIN sys.dm_exec_query_memory_grants AS mg
        ON r.session_id = mg.session_id
           AND r.request_id = mg.request_id
    CROSS APPLY sys.dm_exec_sql_text(mg.sql_handle) AS txt
    CROSS APPLY sys.dm_exec_query_plan(r.plan_handle) AS qp
ORDER BY mg.granted_memory_kb DESC;

Adatbázisok és objektumok méretének kiszámítása

Az alábbi lekérdezés visszaadja az adatbázis méretét (megabájtban):

-- Calculates the size of the database.
SELECT SUM(CAST(FILEPROPERTY(name, 'SpaceUsed') AS bigint) * 8192.) / 1024 / 1024 AS DatabaseSizeInMB
FROM sys.database_files
WHERE type_desc = 'ROWS';
GO

Az alábbi lekérdezés visszaadja az adatbázisban található egyes objektumok méretét (megabájtban):

-- Calculates the size of individual database objects.
SELECT sys.objects.name, SUM(reserved_page_count) * 8.0 / 1024
FROM sys.dm_db_partition_stats, sys.objects
WHERE sys.dm_db_partition_stats.object_id = sys.objects.object_id
GROUP BY sys.objects.name;
GO

Kapcsolatok monitorozása

A sys.dm_exec_connections nézet segítségével lekérheti az adott felügyelt példányhoz létrehozott kapcsolatokra és az egyes kapcsolatok részleteire vonatkozó információkat. Emellett a sys.dm_exec_sessions nézet hasznos az összes aktív felhasználói kapcsolatra és belső feladatra vonatkozó információk lekérésekor.

Az alábbi lekérdezés az aktuális kapcsolat adatait kéri le:

SELECT
    c.session_id, c.net_transport, c.encrypt_option,
    c.auth_scheme, s.host_name, s.program_name,
    s.client_interface_name, s.login_name, s.nt_domain,
    s.nt_user_name, s.original_login_name, c.connect_time,
    s.login_time
FROM sys.dm_exec_connections AS c
JOIN sys.dm_exec_sessions AS s
    ON c.session_id = s.session_id
WHERE c.session_id = @@SPID;

Erőforrás-használat figyelése

Az erőforrás-használatot ugyanúgy figyelheti a Lekérdezéstár használatával, mint az SQL Serverben.

A használatot sys.dm_db_resource_stats és sys.server_resource_stats is figyelheti.

sys.dm_db_resource_stats

A sys.dm_db_resource_stats nézetet minden adatbázisban használhatja. A sys.dm_db_resource_stats nézet a szolgáltatási szinthez viszonyított legutóbbi erőforrás-használati adatokat jeleníti meg. A processzor, az adat-IO, a naplóírás és a memória átlagos százalékos értékeit 15 másodpercenként rögzíti a rendszer, és 1 órán keresztül tartja karban.

Mivel ez a nézet részletesebben szemlélteti az erőforrások használatát, először használja sys.dm_db_resource_stats az aktuális állapotelemzéshez vagy hibaelhárításhoz. Ez a lekérdezés például az aktuális adatbázis átlagos és maximális erőforrás-használatát mutatja az elmúlt egy órában:

SELECT  
    AVG(avg_cpu_percent) AS 'Average CPU use in percent',
    MAX(avg_cpu_percent) AS 'Maximum CPU use in percent',
    AVG(avg_data_io_percent) AS 'Average data IO in percent',
    MAX(avg_data_io_percent) AS 'Maximum data IO in percent',
    AVG(avg_log_write_percent) AS 'Average log write use in percent',
    MAX(avg_log_write_percent) AS 'Maximum log write use in percent',
    AVG(avg_memory_usage_percent) AS 'Average memory use in percent',
    MAX(avg_memory_usage_percent) AS 'Maximum memory use in percent'
FROM sys.dm_db_resource_stats;  

Egyéb lekérdezések esetén lásd a sys.dm_db_resource_stats példákat.

sys.server_resource_stats

A sys.server_resource_stats használatával visszaadhatja a felügyelt Azure SQL-példány processzorhasználati, I/O- és tárolási adatait. Az adatok összegyűjtése és összesítése ötperces időközönként történik. 15 másodpercenként egy sorból áll a jelentés. A visszaadott adatok közé tartozik a processzorhasználat, a tárterület mérete, az IO-kihasználtság és a felügyelt példány termékváltozata. Az előzményadatok körülbelül 14 napig maradnak meg.

A példák különböző módszereket mutatnak be, amelyekkel a sys.server_resource_stats katalógusnézet segítségével információkat kaphat arról, hogy a példány hogyan használja az erőforrásokat.

  1. Az alábbi példa az elmúlt hét nap átlagos processzorhasználatát adja vissza:

    DECLARE @s datetime;  
    DECLARE @e datetime;  
    SET @s= DateAdd(d,-7,GetUTCDate());  
    SET @e= GETUTCDATE();  
    SELECT AVG(avg_cpu_percent) AS Average_Compute_Utilization   
    FROM sys.server_resource_stats   
    WHERE start_time BETWEEN @s AND @e;
    GO
    
  2. Az alábbi példa a példány által naponta használt átlagos tárterületet adja vissza a növekedés trendjének elemzéséhez:

    DECLARE @s datetime;  
    DECLARE @e datetime;  
    SET @s= DateAdd(d,-7,GetUTCDate());  
    SET @e= GETUTCDATE();  
    SELECT Day = convert(date, start_time), AVG(storage_space_used_mb) AS Average_Space_Used_mb
    FROM sys.server_resource_stats   
    WHERE start_time BETWEEN @s AND @e
    GROUP BY convert(date, start_time)
    ORDER BY convert(date, start_time);
    GO
    

Egyidejű kérelmek maximális száma

Az egyidejű kérések aktuális számának megtekintéséhez futtassa ezt a Transact-SQL-lekérdezést az adatbázisban:

SELECT COUNT(*) AS [Concurrent_Requests]
FROM sys.dm_exec_requests R;

Az egyes adatbázisok számítási feladatainak elemzéséhez módosítsa ezt a lekérdezést úgy, hogy az az elemezni kívánt adatbázisra szűrjön. Ha például van egy adatbázis neve MyDatabase, ez a Transact-SQL-lekérdezés az adatbázisban lévő egyidejű kérések számát adja vissza:

SELECT COUNT(*) AS [Concurrent_Requests]
FROM sys.dm_exec_requests R
INNER JOIN sys.databases D ON D.database_id = R.database_id
AND D.name = 'MyDatabase';

Ez csak pillanatkép egy adott időpontban. A számítási feladatok és az egyidejű kérések követelményeinek jobb megismeréséhez idővel számos mintát kell összegyűjtenie.

Egyidejű bejelentkezések maximális száma

A felhasználói és alkalmazásminták elemzésével képet kaphat a bejelentkezések gyakoriságáról. A valós terheléseket tesztkörnyezetben is futtathatja, így meggyőződhet arról, hogy nem éri el ezt vagy a cikkben tárgyalt egyéb korlátokat. Nincs egyetlen lekérdezési vagy dinamikus felügyeleti nézet (DMV), amely megjelenítheti az egyidejű bejelentkezések számát vagy előzményeit.

Ha több ügyfél ugyanazt a kapcsolati sztring használja, a szolgáltatás minden bejelentkezést hitelesít. Ha 10 felhasználó egyidejűleg ugyanazzal a felhasználónévvel és jelszóval csatlakozik egy adatbázishoz, 10 egyidejű bejelentkezés lenne. Ez a korlát csak a bejelentkezés és a hitelesítés időtartamára vonatkozik. Ha ugyanaz a 10 felhasználó egymás után csatlakozik az adatbázishoz, az egyidejű bejelentkezések száma soha nem lenne nagyobb 1-nél.

Munkamenetek maximális száma

Az aktuális aktív munkamenetek számának megtekintéséhez futtassa ezt a Transact-SQL-lekérdezést az adatbázisban:

SELECT COUNT(*) AS [Sessions]
FROM sys.dm_exec_connections;

Ha SQL Server-számítási feladatot elemez, módosítsa úgy a lekérdezést, hogy egy adott adatbázisra összpontosítson. Ez a lekérdezés segít meghatározni az adatbázis lehetséges munkamenet-igényeit, ha azt tervezi, hogy áthelyezi az Azure-ba.

SELECT COUNT(*) AS [Sessions]
FROM sys.dm_exec_connections C
INNER JOIN sys.dm_exec_sessions S ON (S.session_id = C.session_id)
INNER JOIN sys.databases D ON (D.database_id = S.database_id)
WHERE D.name = 'MyDatabase';

Ezek a lekérdezések ismét időponthoz kötött számot adnak vissza. Ha több mintát gyűjt idővel, akkor a legjobban ismeri a munkamenet-használatot.

Lekérdezés teljesítményének monitorozása

A lassú vagy hosszú ideig futó lekérdezések jelentős rendszererőforrásokat használhatnak fel. Ez a szakasz bemutatja, hogyan használható dinamikus felügyeleti nézetek néhány gyakori lekérdezési teljesítményproblémára.

A leggyakoribb N-lekérdezések keresése

Az alábbi példa az átlagos CPU-idő alapján rangsorolt első öt lekérdezés adatait adja vissza. Ez a példa a lekérdezéseket a lekérdezés kivonata alapján összesíti, így a logikailag egyenértékű lekérdezések az összesített erőforrás-felhasználásuk szerint vannak csoportosítva.

SELECT TOP 5 query_stats.query_hash AS "Query Hash",
    SUM(query_stats.total_worker_time) / SUM(query_stats.execution_count) AS "Avg CPU Time",
     MIN(query_stats.statement_text) AS "Statement Text"
FROM
    (SELECT QS.*,
        SUBSTRING(ST.text, (QS.statement_start_offset/2) + 1,
            ((CASE statement_end_offset
                WHEN -1 THEN DATALENGTH(ST.text)
                ELSE QS.statement_end_offset END
            - QS.statement_start_offset)/2) + 1) AS statement_text
FROM sys.dm_exec_query_stats AS QS
CROSS APPLY sys.dm_exec_sql_text(QS.sql_handle) as ST) as query_stats
GROUP BY query_stats.query_hash
ORDER BY 2 DESC;

Letiltott lekérdezések figyelése

A lassú vagy hosszú ideig futó lekérdezések hozzájárulhatnak a túlzott erőforrás-felhasználáshoz, és a blokkolt lekérdezések következményei lehetnek. A blokkolás oka lehet az alkalmazás rossz kialakítása, a rossz lekérdezési tervek, a hasznos indexek hiánya stb. A sys.dm_tran_locks nézetben információkat kaphat az adatbázis aktuális zárolási tevékenységéről. Lásd például a sys.dm_tran_locks. A blokkolás hibaelhárításával kapcsolatos további információkért tekintse meg és oldja meg az Azure SQL blokkolási problémáit.

Holtpontok monitorozása

Bizonyos esetekben két vagy több lekérdezés egymás kölcsönösen blokkolhatja egymást, ami holtpontot eredményez.

Létrehozhat egy kiterjesztett eseményeket, amelyek egy adatbázist követve rögzítik a holtponti eseményeket, majd megkereshetik a kapcsolódó lekérdezéseket és azok végrehajtási terveit a Lekérdezéstárban.

Felügyelt Azure SQL-példány esetén tekintse meg a holtpont eszközeit a Holtpontok útmutatójában.

Lekérdezéstervek figyelése

A nem hatékony lekérdezési terv a processzorhasználatot is növelheti. Az alábbi példa a sys.dm_exec_query_stats nézetet használja annak meghatározására, hogy melyik lekérdezés használja a legnagyobb összegző processzort.

SELECT
    highest_cpu_queries.plan_handle,
    highest_cpu_queries.total_worker_time,
    q.dbid,
    q.objectid,
    q.number,
    q.encrypted,
    q.[text]
FROM
    (SELECT TOP 50
        qs.plan_handle,
        qs.total_worker_time
    FROM
        sys.dm_exec_query_stats qs
ORDER BY qs.total_worker_time desc) AS highest_cpu_queries
CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS q
ORDER BY highest_cpu_queries.total_worker_time DESC;

Egyéb figyelési lehetőségek

Monitorozás SQL Elemzések (előzetes verzió)

Az Azure Monitor SQL Elemzések (előzetes verzió) egy eszköz a felügyelt Azure SQL-példányok, az Azure SQL Database-adatbázisok és az Azure SQL-alapú virtuális gépeken futó SQL Server monitorozására. A szolgáltatás egy távoli ügynök segítségével rögzít adatokat a dinamikus felügyeleti nézetekből (DMV-kből), majd továbbítja az adatokat az Azure Log Analyticsnek, ahol az adatok monitorozhatók és elemezhetők. Ezeket az adatokat a megadott nézetekben tekintheti meg az Azure Monitorból, vagy közvetlenül hozzáférhet a naplóadatokhoz lekérdezések futtatásához és trendek elemzéséhez. Az Azure Monitor SQL Elemzések (előzetes verzió) használatának megkezdéséhez tekintse meg az SQL Elemzések engedélyezése (előzetes verzió) című témakört.

Monitorozás az Azure Monitorral

Az Azure Monitor számos diagnosztikai adatgyűjtési csoportot, metrikát és végpontot biztosít a felügyelt Azure SQL-példány figyeléséhez. További információ: Felügyelt Azure SQL-példány monitorozása az Azure Monitorral. Az Azure SQL Analytics (előzetes verzió) egy integráció az Azure Monitorral, ahol számos monitorozási megoldás már nem aktív fejlesztés alatt áll. További monitorozási lehetőségekért tekintse meg a felügyelt Azure SQL-példány és az Azure SQL Database monitorozását és teljesítményhangolását.

Lásd még

Következő lépések