動的管理ビューを使用した Microsoft Azure SQL Database および Azure SQL Managed Instance のパフォーマンスの監視Monitoring Microsoft Azure SQL Database and Azure SQL Managed Instance performance using dynamic management views

適用対象: Azure SQL Database Azure SQL Managed Instance

Microsoft Azure SQL Database および Azure SQL Managed Instance では、クエリのブロック、クエリの長時間実行、リソースのボトルネック、不適切なクエリ プランなどが原因で発生するパフォーマンスの問題を、動的管理ビューの一部を使用して診断できます。Microsoft Azure SQL Database and Azure SQL Managed Instance enable a subset of dynamic management views to diagnose performance problems, which might be caused by blocked or long-running queries, resource bottlenecks, poor query plans, and so on. この記事では、動的管理ビューを使用して一般的なパフォーマンスの問題を検出する方法について説明します。This article provides information on how to detect common performance problems by using dynamic management views.

Microsoft Azure SQL Database および Azure SQL Managed Instance では、動的管理ビューの 3 つのカテゴリが部分的にサポートされています。Microsoft Azure SQL Database and Azure SQL Managed Instance partially support three categories of dynamic management views:

  • データベース関連の動的管理ビュー。Database-related dynamic management views.
  • 実行関連の動的管理ビュー。Execution-related dynamic management views.
  • トランザクション関連の動的管理ビュー。Transaction-related dynamic management views.

動的管理ビューの詳細については、動的管理ビューおよび関数 (Transact-SQL) に関する記事をご覧ください。For detailed information on dynamic management views, see Dynamic Management Views and Functions (Transact-SQL).

アクセス許可Permissions

Azure SQL Database で、動的管理ビューに対してクエリを実行するには、VIEW DATABASE STATE アクセス許可が必要です。In Azure SQL Database, querying a dynamic management view requires VIEW DATABASE STATE permissions. VIEW DATABASE STATE アクセス許可は、現在のデータベース内のすべてのオブジェクトに関する情報を返します。The VIEW DATABASE STATE permission returns information about all objects within the current database. VIEW DATABASE STATE アクセス許可を特定のデータベース ユーザーに付与するには、次のクエリを実行します。To grant the VIEW DATABASE STATE permission to a specific database user, run the following query:

GRANT VIEW DATABASE STATE TO database_user;

Azure SQL Managed Instance で、動的管理ビューに対してクエリを実行するには、VIEW SERVER STATE アクセス許可が必要です。In Azure SQL Managed Instance, querying a dynamic management view requires VIEW SERVER STATE permissions. 詳細については、「システム動的管理ビュー」を参照してください。For more information, see System Dynamic Management Views.

SQL Server のインスタンスおよび Azure SQL Managed Instance では、動的管理ビューにサーバーの状態についての情報が返されます。In an instance of SQL Server and in Azure SQL Managed Instance, dynamic management views return server state information. Azure SQL Database では、現在の論理データベースに関する情報のみが返されます。In Azure SQL Database, they return information regarding your current logical database only.

この記事には、次の種類のクエリ パフォーマンスの問題を検出するために、SQL Server Management Studio または Azure Data Studio を使用して実行できる DMV クエリのコレクションが含まれています。This article contains a collection of DMV queries that you can execute using SQL Server Management Studio or Azure Data Studio to detect the following types of query performance issues:

CPU パフォーマンスに関する問題の特定Identify CPU performance issues

CPU 消費率が長時間 80% を超えている場合は、次のトラブルシューティングの手順を検討してください。If CPU consumption is above 80% for extended periods of time, consider the following troubleshooting steps:

CPU に関する問題が現在発生しているThe CPU issue is occurring now

現時点で問題が発生している場合、2 つのシナリオが考えられます。If issue is occurring right now, there are two possible scenarios:

個別のクエリが多数あり、大量の CPU が累積的に消費されているMany individual queries that cumulatively consume high CPU

上位のクエリ ハッシュを特定するには、次のクエリを使用します。Use the following query to identify top query hashes:

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;

実行時間の長いクエリが CPU を消費しており、実行中のままであるLong running queries that consume CPU are still running

これらのクエリを特定するには、次のクエリを使用します。Use the following query to identify these queries:

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

CPU に関する問題が過去に発生したThe CPU issue occurred in the past

過去に問題が発生していて、根本原因分析を行いたい場合は、クエリ ストアを使用します。If the issue occurred in the past and you want to do root cause analysis, use Query Store. データベースにアクセスできるユーザーは、T-SQL を使用して、クエリ ストア データにクエリを実行できます。Users with database access can use T-SQL to query Query Store data. クエリ ストアの既定の構成では、1 時間の粒度が使用されます。Query Store default configurations use a granularity of 1 hour. 大量の CPU を消費するクエリのアクティビティを確認するには、次のクエリを使用します。Use the following query to look at activity for high CPU consuming queries. このクエリは、CPU の消費が上位 15 のクエリを返します。This query returns the top 15 CPU consuming queries. 必ず rsi.start_time >= DATEADD(hour, -2, GETUTCDATE() を変更してください。Remember to change 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;

問題となるクエリを特定したら、今度はそれらのクエリを調整して、CPU 使用率を抑えます。Once you identify the problematic queries, it's time to tune those queries to reduce CPU utilization. クエリを調整する時間がない場合は、問題を回避するためにデータベースの SLO をアップグレードすることもできます。If you don't have time to tune the queries, you may also choose to upgrade the SLO of the database to work around the issue.

IO パフォーマンスに関する問題の特定Identify IO performance issues

IO パフォーマンスに関する問題を特定する場合、IO の問題に関連している待機の種類のうち、上位のものは以下になります。When identifying IO performance issues, the top wait types associated with IO issues are:

  • PAGEIOLATCH_*

    データ ファイル IO に関する問題の場合 (PAGEIOLATCH_SHPAGEIOLATCH_EXPAGEIOLATCH_UP など)。For data file IO issues (including PAGEIOLATCH_SH, PAGEIOLATCH_EX, PAGEIOLATCH_UP). 待機の種類の名前に IO が含まれている場合は、それにより IO に関する問題が示されます。If the wait type name has IO in it, it points to an IO issue. ページ ラッチ待機の名前に IO が含まれていない場合は、それにより別の種類の問題 (例: tempdb の競合) が示されます。If there is no IO in the page latch wait name, it points to a different type of problem (for example, tempdb contention).

  • WRITE_LOG

    トランザクション ログ IO に関する問題の場合。For transaction log IO issues.

IO に関する問題が現時点で発生している場合If the IO issue is occurring right now

sys.dm_exec_requests または sys.dm_os_waiting_tasks を使用して、wait_typewait_time を確認します。Use the sys.dm_exec_requests or sys.dm_os_waiting_tasks to see the wait_type and wait_time.

データ IO およびログ IO の使用率の特定Identify data and log IO usage

データ IO およびログ IO の使用率を特定するには、次のクエリを使用します。Use the following query to identify data and log IO usage. データまたはログ IO が 80% を超えている状態は、ユーザーがその SQL Database サービス レベルで利用可能な IO を利用したことを意味します。If the data or log IO is above 80%, it means users have used the available IO for the SQL Database service tier.

SELECT end_time, avg_data_io_percent, avg_log_write_percent
FROM sys.dm_db_resource_stats
ORDER BY end_time DESC;

IO の上限に達した場合は 2 つのオプションがあります。If the IO limit has been reached, you have two options:

  • オプション 1: コンピューティング サイズまたはサービス レベルをアップグレードするOption 1: Upgrade the compute size or service tier
  • オプション 2:最も多くの IO を消費しているクエリを特定して調整するOption 2: Identify and tune the queries consuming the most IO.

オプション 2 では、バッファー関連 IO についてクエリ ストアに対して次のクエリを実行して、過去 2 時間の追跡されたアクティビティを表示できます。For option 2, you can use the following query against Query Store for buffer-related IO to view the last two hours of tracked activity:

-- 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

WRITELOG 待機に関する合計ログ IO の表示View total log IO for WRITELOG waits

待機の種類が WRITELOG の場合、次のクエリを使用して、ステートメントごとに合計ログ IO を表示します。If the wait type is WRITELOG, use the following query to view total log IO by statement:

-- 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

tempdb パフォーマンスに関する問題の特定Identify tempdb performance issues

IO パフォーマンスに関する問題を特定する場合、tempdb の問題に関連している待機の種類の上位は PAGELATCH_* です (PAGEIOLATCH_* ではありません)。When identifying IO performance issues, the top wait types associated with tempdb issues is PAGELATCH_* (not PAGEIOLATCH_*). ただし、PAGELATCH_* 待機は必ずしも tempdb 競合があることを意味しません。However, PAGELATCH_* waits do not always mean you have tempdb contention. この待機は、同一のデータ ページを対象とする同時要求が原因で、ユーザーオブジェクト データ ページ競合が発生していることを意味する場合もあります。This wait may also mean that you have user-object data page contention due to concurrent requests targeting the same data page. tempdb 競合をさらに確認するには、sys.dm_exec_requests を使用して、wait_resource 値が 2:x:y で始まることを確認します。ここで、2 は tempdb (データベース ID)、x はファイル ID、y はページ ID です。To further confirm tempdb contention, use sys.dm_exec_requests to confirm that the wait_resource value begins with 2:x:y where 2 is tempdb is the database ID, x is the file ID, and y is the page ID.

tempdb 競合では、tempdb が使用されるアプリケーション コードを減らすか、書き直すのが一般的な方法です。For tempdb contention, a common method is to reduce or rewrite application code that relies on tempdb. tempdb の一般的な使用領域には以下があります。Common tempdb usage areas include:

  • 一時テーブルTemp tables
  • テーブル変数Table variables
  • テーブル値パラメーターTable-valued parameters
  • バージョン ストアの使用 (実行時間の長いトランザクションに関連)Version store usage (associated with long running transactions)
  • 並べ替え、ハッシュ結合、スプールが使用されるクエリ プランがあるクエリQueries that have query plans that use sorts, hash joins, and spools

テーブル変数と一時テーブルが使用される上位のクエリTop queries that use table variables and temporary tables

テーブル変数と一時テーブルが使用される上位のクエリを特定するには、次のクエリを使用します。Use the following query to identify top queries that use table variables and temporary tables:

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;

実行時間の長いトランザクションの特定Identify long running transactions

実行時間の長いトランザクションを特定するには、次のクエリを使用します。Use the following query to identify long running transactions. 実行時間の長いトランザクションは、バージョン ストアのクリーンアップを妨げます。Long running transactions prevent version store cleanup.

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,
       LTRIM(RTRIM(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;

メモリ許可待機パフォーマンスに関する問題の特定Identify memory grant wait performance issues

上位の待機の種類が RESOURCE_SEMAHPORE であり、なおかつ高 CPU 使用率の問題がない場合は、メモリ許可待機に関する問題が発生している可能性があります。If your top wait type is RESOURCE_SEMAHPORE and you don't have a high CPU usage issue, you may have a memory grant waiting issue.

RESOURCE_SEMAHPORE 待機が上位の待機であるかどうかの確認Determine if a RESOURCE_SEMAHPORE wait is a top wait

RESOURCE_SEMAHPORE 待機が上位の待機であるかどうかを確認するには、次のクエリを使用しますUse the following query to determine if a RESOURCE_SEMAHPORE wait is a top wait

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;

大量のメモリを消費するステートメントの特定Identify high memory-consuming statements

大量のメモリを消費するステートメントを特定するには、次のクエリを使用します。Use the following query to identify high memory-consuming statements:

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;

上位 10 のアクティブなメモリ許可の特定Identify the top 10 active memory grants

上位 10 のアクティブなメモリ許可を特定するには、次のクエリを実行します。Use the following query to identify the top 10 active memory grants:

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',
       LTRIM(RTRIM(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;

データベース サイズとオブジェクト サイズの計算Calculating database and objects sizes

次のクエリは、データベースのサイズ (MB 単位) を返します。The following query returns the size of your database (in megabytes):

-- 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

次のクエリは、データベース内の個々のオブジェクトのサイズ (MB 単位) を返します。The following query returns the size of individual objects (in megabytes) in your database:

-- 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

接続の監視Monitoring connections

sys.dm_exec_connections ビューを使用して、特定のサーバーおよびマネージド インスタンスに対して確立されている接続についての情報と、各接続の詳細を取得できます。You can use the sys.dm_exec_connections view to retrieve information about the connections established to a specific server and managed instance and the details of each connection. また、sys.dm_exec_sessions ビューは、すべてのアクティブなユーザー接続と内部タスクについての情報を取得する場合に役立ちます。In addition, the sys.dm_exec_sessions view is helpful when retrieving information about all active user connections and internal tasks.

次のクエリは、現在の接続に関する情報を取得します。The following query retrieves information on the current connection:

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;

注意

sys.dm_exec_requestssys.dm_exec_sessions views を実行するときに、データベースに対するアクセス許可 VIEW DATABASE STATE を持っていると、データベースで実行中のすべてのセッションが表示されます。アクセス許可を持っていない場合は、現在のセッションのみが表示されます。When executing the sys.dm_exec_requests and sys.dm_exec_sessions views, if you have VIEW DATABASE STATE permission on the database, you see all executing sessions on the database; otherwise, you see only the current session.

リソース使用量の監視Monitor resource use

SQL Database Query Performance Insight を使用して、Azure SQL Database リソースの使用量を監視できます。You can monitor Azure SQL Database resource usage using SQL Database Query Performance Insight. Azure SQL Database および Azure SQL Managed Instance の場合は、クエリ ストアを使用して監視できます。For Azure SQL Database and Azure SQL Managed Instance, you can monitor using Query Store.

また、次のビューを使用して使用量を監視することもできます。You can also monitor usage using these views:

sys.dm_db_resource_statssys.dm_db_resource_stats

sys.dm_db_resource_stats ビューは、すべてのデータベースで使用できます。You can use the sys.dm_db_resource_stats view in every database. sys.dm_db_resource_stats ビューには、サービス レベルに関連した最近のリソース使用率データが表示されます。The sys.dm_db_resource_stats view shows recent resource use data relative to the service tier. CPU、データ IO、ログ書き込み、メモリの平均 (%) が 15 秒ごとに記録され、1 時間保持されます。Average percentages for CPU, data IO, log writes, and memory are recorded every 15 seconds and are maintained for 1 hour.

このビューにはリソース使用率が詳細に表示されるので、現状の分析やトラブルシューティングが目的の場合、最初に sys.dm_db_resource_stats を使用してください。Because this view provides a more granular look at resource use, use sys.dm_db_resource_stats first for any current-state analysis or troubleshooting. たとえば次のクエリは、現在のデータベースの過去 1 時間の平均リソース使用率と最大リソース使用率を表示します。For example, this query shows the average and maximum resource use for the current database over the past hour:

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;  

その他のクエリについては、sys.dm_db_resource_stats の例を参照してください。For other queries, see the examples in sys.dm_db_resource_stats.

sys.server_resource_statssys.server_resource_stats

sys.server_resource_stats を使用すると、Azure SQL Managed Instance の CPU 使用率、IO、ストレージ データが返されます。You can use sys.server_resource_stats to return CPU usage, IO, and storage data for an Azure SQL Managed Instance. データは、5 分間隔で収集と集計が実行されます。The data is collected and aggregated within five-minute intervals. 15 秒ごとの報告につき 1 行作成されます。There is one row for every 15 seconds reporting. 返されるデータには、CPU 使用率、ストレージ サイズ、IO 使用率、マネージド インスタンス SKU が含まれます。The data returned includes CPU usage, storage size, IO utilization, and managed instance SKU. 履歴データは約 14 日間保持されます。Historical data is retained for approximately 14 days.

DECLARE @s datetime;  
DECLARE @e datetime;  
SET @s= DateAdd(d,-7,GetUTCDate());  
SET @e= GETUTCDATE();  
SELECT resource_name, AVG(avg_cpu_percent) AS Average_Compute_Utilization
FROM sys.server_resource_stats
WHERE start_time BETWEEN @s AND @e  
GROUP BY resource_name  
HAVING AVG(avg_cpu_percent) >= 80;

sys.resource_statssys.resource_stats

master データベースの sys.resource_stats ビューには、特定のサービス レベルとコンピューティング サイズでのデータベースのパフォーマンス監視に役立つ追加情報が含まれます。The sys.resource_stats view in the master database has additional information that can help you monitor the performance of your database at its specific service tier and compute size. データは 5 分ごとに集められ、約 14 日間保持されます。The data is collected every 5 minutes and is maintained for approximately 14 days. このビューは、過去にデータベースでリソースがどのように使用されたかを長期にわたり分析する場合に役立ちます。This view is useful for a longer-term historical analysis of how your database uses resources.

次のグラフは、Premium データベースの CPU リソース使用率を示しています (P2 コンピューティング サイズ、1 週間における毎時間の使用率)。The following graph shows the CPU resource use for a Premium database with the P2 compute size for each hour in a week. このグラフは月曜日から始まります。5 営業日が経過した後の週末ではアプリケーションの活動が大幅に減っていることがわかります。This graph starts on a Monday, shows five work days, and then shows a weekend, when much less happens on the application.

データベース リソースの使用

このデータから、このデータベースのピーク CPU 負荷は現在のところ、P2 コンピューティング サイズに対して 50% をわずかに超える CPU 利用率になっていることがわかります (火曜日の昼)。From the data, this database currently has a peak CPU load of just over 50 percent CPU use relative to the P2 compute size (midday on Tuesday). アプリケーションのリソース プロファイルにおいて CPU が支配的要因である場合、P2 がワークロードに常に対処できる最適なコンピューティング サイズであると決定できます。If CPU is the dominant factor in the application's resource profile, then you might decide that P2 is the right compute size to guarantee that the workload always fits. 時間の経過と共にアプリケーションの規模が大きくなると予測される場合、アプリケーションがパフォーマンス レベルの制限に達しないように、リソース バッファーを余分に確保しておくことをお勧めします。If you expect an application to grow over time, it's a good idea to have an extra resource buffer so that the application doesn't ever reach the performance-level limit. コンピューティング サイズを上げると、要求を効果的に処理するための十分な能力がないデータベースで発生するおそれのある、ユーザーに見えるエラーを回避できます。これは特に待機時間が重要な環境に当てはまります。If you increase the compute size, you can help avoid customer-visible errors that might occur when a database doesn't have enough power to process requests effectively, especially in latency-sensitive environments. たとえば、データベース呼び出しの結果に基づいて Web ページを描画するアプリケーションをサポートしているデータベースなどです。An example is a database that supports an application that paints webpages based on the results of database calls.

アプリケーションの種類が異なれば、同じグラフの解釈が異なる場合があります。Other application types might interpret the same graph differently. たとえば、あるアプリケーションで給与データを毎日処理し、同じグラフを生成する場合、P1 コンピューティング サイズでこの種の "一括ジョブ" モデルに問題なく対応できる可能性があります。For example, if an application tries to process payroll data each day and has the same chart, this kind of "batch job" model might do fine at a P1 compute size. P2 コンピューティング サイズが 200 DTU であるのに対して、P1 コンピューティング サイズは 100 DTU です。The P1 compute size has 100 DTUs compared to 200 DTUs at the P2 compute size. P1 コンピューティング サイズのパフォーマンスは、P2 コンピューティング サイズの半分です。The P1 compute size provides half the performance of the P2 compute size. このため、P2 における 50% の CPU 使用率は、P1 における 100% の CPU 使用率に相当します。So, 50 percent of CPU use in P2 equals 100 percent CPU use in P1. アプリケーションにタイムアウトがない場合、当日に完了するのであれば、ジョブに 2 時間かかっても 2.5 時間かかっても問題ないものと思われます。If the application does not have timeouts, it might not matter if a job takes 2 hours or 2.5 hours to finish, if it gets done today. このカテゴリのアプリケーションではおそらく、P1 コンピューティング サイズを利用できます。An application in this category probably can use a P1 compute size. 1 日の中にはリソース使用率が低くなる時間帯があるという事実を利用できます。このため、"大きなピーク" が 1 日のそのような時間帯のいずれかに波及することがあります。You can take advantage of the fact that there are periods of time during the day when resource use is lower, so that any "big peak" might spill over into one of the troughs later in the day. ジョブを毎日定刻に完了できる限り、P1 コンピューティング サイズがこの種のアプリケーションに適している (コストが削減される) 場合があります。The P1 compute size might be good for that kind of application (and save money), as long as the jobs can finish on time each day.

データベース エンジンでは、各アクティブ データベースの使用済みリソース情報が、各サーバーの master データベースの sys.resource_stats ビューで公開されます。The database engine exposes consumed resource information for each active database in the sys.resource_stats view of the master database in each server. テーブルのデータは 5 分おきに集計されます。The data in the table is aggregated for 5-minute intervals. Basic、Standard、Premium のサービス レベルでは、データをテーブルに表示するのに 5 分を超える時間がかかる可能性があります。このため、このデータはほぼリアルタイムの分析よりも過去の分析に役に立ちます。With the Basic, Standard, and Premium service tiers, the data can take more than 5 minutes to appear in the table, so this data is more useful for historical analysis rather than near-real-time analysis. sys.resource_stats ビューに照会すると、データベースの最近の履歴が表示され、選択した予約で必要なときに望ましいパフォーマンスが発揮されたかどうかを検証できます。Query the sys.resource_stats view to see the recent history of a database and to validate whether the reservation you chose delivered the performance you want when needed.

注意

Azure SQL Database で、次の例の sys.resource_stats にクエリを実行するには、master データベースに接続する必要があります。On Azure SQL Database, you must be connected to the master database to query sys.resource_stats in the following examples.

次の例は、このビューのデータが表示されているところです。This example shows you how the data in this view is exposed:

SELECT TOP 10 *
FROM sys.resource_stats
WHERE database_name = 'resource1'
ORDER BY start_time DESC;

The sys.resource_stats catalog view

次の例では、sys.resource_stats カタログ ビューを使用して、データベースでのリソースの使用状況に関する情報を取得するさまざまな方法を示します。The next example shows you different ways that you can use the sys.resource_stats catalog view to get information about how your database uses resources:

  1. データベース userdb1 の過去 1 週間のリソース使用率を確認するには、このクエリを実行します。To look at the past week's resource use for the database userdb1, you can run this query:

    SELECT *
    FROM sys.resource_stats
    WHERE database_name = 'userdb1' AND
        start_time > DATEADD(day, -7, GETDATE())
    ORDER BY start_time DESC;
    
  2. ワークロードがコンピューティング サイズにどの程度適合しているかを評価するには、リソース メトリックの各側面を分析する必要があります。つまり、CPU、読み取り、書き込み、ワーカー数、セッション数です。To evaluate how well your workload fits the compute size, you need to drill down into each aspect of the resource metrics: CPU, reads, writes, number of workers, and number of sessions. 次に、sys.resource_stats を使用してこれらのリソース メトリックの平均値と最大値を報告するように修正したクエリを示します:Here's a revised query using sys.resource_stats to report the average and maximum values of these resource metrics:

    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 physical data IO use in percent',
        max(avg_data_io_percent) AS 'Maximum physical data IO use 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(max_session_percent) AS 'Average % of sessions',
        max(max_session_percent) AS 'Maximum % of sessions',
        avg(max_worker_percent) AS 'Average % of workers',
        max(max_worker_percent) AS 'Maximum % of workers'
    FROM sys.resource_stats
    WHERE database_name = 'userdb1' AND start_time > DATEADD(day, -7, GETDATE());
    
  3. 各リソース メトリックの平均値と最大値に関するこの情報に基づいて、選択したコンピューティング サイズにワークロードが適合しているかどうかを評価できます。With this information about the average and maximum values of each resource metric, you can assess how well your workload fits into the compute size you chose. 通常、sys.resource_stats からの平均値が目標サイズに対する有効な基準となります。Usually, average values from sys.resource_stats give you a good baseline to use against the target size. これを主要なものさしとしてください。It should be your primary measurement stick. たとえば、S2 コンピューティング サイズで Standard サービス レベルを使用しているとします。For an example, you might be using the Standard service tier with S2 compute size. CPU と IO の読み取り/書き込みの平均使用率が 40% を下回り、ワーカーの平均数が 50 を下回り、セッションの平均数が 200 を下回っています。The average use percentages for CPU and IO reads and writes are below 40 percent, the average number of workers is below 50, and the average number of sessions is below 200. このワークロードには、S1 コンピューティング サイズが適している可能性があります。Your workload might fit into the S1 compute size. データベースがワーカーとセッションの制限内に収まるかどうかは簡単にわかります。It's easy to see whether your database fits in the worker and session limits. CPU、読み取り、書き込みに関して、データベースが下位のコンピューティング サイズに適合するかどうかを確認するには、下位コンピューティング サイズの DTU 数を現在のコンピューティング サイズの DTU 数で割り、その計算結果に 100 を掛けます。To see whether a database fits into a lower compute size with regard to CPU, reads, and writes, divide the DTU number of the lower compute size by the DTU number of your current compute size, and then multiply the result by 100:

    S1 DTU / S2 DTU * 100 = 20 / 50 * 100 = 40

    この結果は、2 つのコンピューティング サイズの間の相対的パフォーマンス差異を百分率で表したものになります。The result is the relative performance difference between the two compute sizes in percentage. リソースの使用がこの量を超えていない場合、ワークロードは下位のコンピューティング サイズに適合する可能性があります。If your resource use doesn't exceed this amount, your workload might fit into the lower compute size. ただし、リソース使用率の値を全範囲で見て、どのくらいの頻度でデータベースのワークロードが下位のコンピューティング サイズに適合するかを割合の観点から判断する必要があります。However, you need to look at all ranges of resource use values, and determine, by percentage, how often your database workload would fit into the lower compute size. 次のクエリは、この例で計算した 40% のしきい値に基づき、リソース ディメンション別の適合率を出力します。The following query outputs the fit percentage per resource dimension, based on the threshold of 40 percent that we calculated in this example:

     SELECT
         (COUNT(database_name) - SUM(CASE WHEN avg_cpu_percent >= 40 THEN 1 ELSE 0 END) * 1.0) / COUNT(database_name) AS 'CPU Fit Percent',
         (COUNT(database_name) - SUM(CASE WHEN avg_log_write_percent >= 40 THEN 1 ELSE 0 END) * 1.0) / COUNT(database_name) AS 'Log Write Fit Percent',
         (COUNT(database_name) - SUM(CASE WHEN avg_data_io_percent >= 40 THEN 1 ELSE 0 END) * 1.0) / COUNT(database_name) AS 'Physical Data IO Fit Percent'
     FROM sys.resource_stats
     WHERE database_name = 'userdb1' AND start_time > DATEADD(day, -7, GETDATE());
    

    データベースのサービス レベルに基づき、ワークロードが下位のコンピューティング サイズに適合するかどうかを判断できます。Based on your database service tier, you can decide whether your workload fits into the lower compute size. データベース ワークロード目標が 99.9% で、上記のクエリが 3 つすべてのリソース ディメンションに対して 99.9% を超える値を返す場合、そのワークロードはおそらく下位のコンピューティング サイズに適合します。If your database workload objective is 99.9 percent and the preceding query returns values greater than 99.9 percent for all three resource dimensions, your workload likely fits into the lower compute size.

    適合率を見ると、目標を満たすために上位のコンピューティング サイズに移行する必要があるかどうかもわかります。Looking at the fit percentage also gives you insight into whether you should move to the next higher compute size to meet your objective. たとえば、userdb1 では過去 1 週間の CPU 使用率が次のようになっています。For example, userdb1 shows the following CPU use for the past week:

    平均 CPU 使用率 (%)Average CPU percent 最大 CPU 使用率 (%)Maximum CPU percent
    24.524.5 100.00100.00

    平均 CPU は、コンピューティング サイズの制限の約 4 分の 1 であり、データベースのコンピューティング サイズにうまく適合するでしょう。The average CPU is about a quarter of the limit of the compute size, which would fit well into the compute size of the database. ただし最大値は、データベースがコンピューティング サイズの制限に到達することを示しています。But, the maximum value shows that the database reaches the limit of the compute size. 次に上位のコンピューティング サイズに移動する必要がありますか。Do you need to move to the next higher compute size? ワークロードが 100% に到達する回数を確認し、それをデータベースのワークロード目標と比較します。Look at how many times your workload reaches 100 percent, and then compare it to your database workload objective.

    SELECT
        (COUNT(database_name) - SUM(CASE WHEN avg_cpu_percent >= 100 THEN 1 ELSE 0 END) * 1.0) / COUNT(database_name) AS 'CPU fit percent'
        ,(COUNT(database_name) - SUM(CASE WHEN avg_log_write_percent >= 100 THEN 1 ELSE 0 END) * 1.0) / COUNT(database_name) AS 'Log write fit percent'
        ,(COUNT(database_name) - SUM(CASE WHEN avg_data_io_percent >= 100 THEN 1 ELSE 0 END) * 1.0) / COUNT(database_name) AS 'Physical data IO fit percent'
        FROM sys.resource_stats
        WHERE database_name = 'userdb1' AND start_time > DATEADD(day, -7, GETDATE());
    

    このクエリが 3 つのリソース ディメンションのいずれにも 99.9% 未満の値を返す場合、次の上位のコンピューティング サイズに移行すること、またはアプリケーションの調整手法を使用してデータベースの負荷を減らすことを検討してください。If this query returns a value less than 99.9 percent for any of the three resource dimensions, consider either moving to the next higher compute size or use application-tuning techniques to reduce the load on the database.

  4. この演習では、予測される将来のワークロードの増加も考慮しています。This exercise also considers your projected workload increase in the future.

エラスティック プールでは、このセクションで説明した手法を使用して、プール内の個々のデータベースを監視できます。For elastic pools, you can monitor individual databases in the pool with the techniques described in this section. ただし、プールを全体として監視することもできます。But you can also monitor the pool as a whole. 詳細については、エラスティック プールの監視と管理に関する記事を参照してください。For information, see Monitor and manage an elastic pool.

同時要求の最大数Maximum concurrent requests

同時要求の数を確認するには、データベースで次の Transact-SQL クエリを実行します。To see the number of concurrent requests, run this Transact-SQL query on your database:

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

SQL Server データベースのワークロードを分析するには、分析したい特定のデータベースでフィルター処理するようにこのクエリを変更します。To analyze the workload of a SQL Server database, modify this query to filter on the specific database you want to analyze. たとえば、MyDatabase という名前のオンプレミス データベースがある場合、次の Transact-SQL クエリはそのデータベースの同時要求の数を返します。For example, if you have an on-premises database named MyDatabase, this Transact-SQL query returns the count of concurrent requests in that database:

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';

これはある時点のスナップショットにすぎません。This is just a snapshot at a single point in time. ワークロードと同時要求の要件をさらに詳しく理解するには、時間をかけて多くのサンプルを収集する必要があります。To get a better understanding of your workload and concurrent request requirements, you'll need to collect many samples over time.

同時ログインの最大数Maximum concurrent logins

ユーザーやアプリケーションのパターンを分析すれば、ログインの頻度を理解できます。You can analyze your user and application patterns to get an idea of the frequency of logins. さらに、テスト環境で実際の負荷を実行し、この上限やこの記事で説明されている他の制限に達していないことを確認できます。You also can run real-world loads in a test environment to make sure that you're not hitting this or other limits we discuss in this article. 同時ログイン数または履歴を表示できる単一のクエリや動的管理ビュー (DMV) はありません。There isn't a single query or dynamic management view (DMV) that can show you concurrent login counts or history.

複数のクライアントで同じ接続文字列を使用している場合、サービスによってそれぞれのログインが認証されます。If multiple clients use the same connection string, the service authenticates each login. 10 人のユーザーが同じユーザー名とパスワードを使ってデータベースに同時に接続した場合、10 件の同時ログインが発生します。If 10 users simultaneously connect to a database by using the same username and password, there would be 10 concurrent logins. この制限は、ログインと認証の期間のみに適用されます。This limit applies only to the duration of the login and authentication. 同じ 10 人のユーザーがデータベースに順番に接続した場合、同時ログイン数が 1 より大きくなることはありません。If the same 10 users connect to the database sequentially, the number of concurrent logins would never be greater than 1.

注意

この制限は現在のところ、エラスティック プールのデータベースには適用されません。Currently, this limit does not apply to databases in elastic pools.

セッションの最大数Maximum sessions

現在アクティブなセッションの数を確認するには、データベースで次の Transact-SQL クエリを実行します。To see the number of current active sessions, run this Transact-SQL query on your database:

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

SQL Server のワークロードを分析する場合は、特定のデータベースが対象になるようにクエリを変更してください。If you're analyzing a SQL Server workload, modify the query to focus on a specific database. このクエリは、Azure への移行を検討している場合に、データベースの潜在的なセッションのニーズを判断するのに役立ちます。This query helps you determine possible session needs for the database if you are considering moving it to Azure.

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';

ここでも、これらのクエリはある時点の数を返します。Again, these queries return a point-in-time count. 時間をかけて複数のサンプルを集めると、セッションの使用状況を正確に把握できます。If you collect multiple samples over time, you'll have the best understanding of your session use.

sys.resource_stats ビューにクエリを実行し、active_session_count 列を確認して、セッションの過去の統計値を取得できます。You can get historical statistics on sessions by querying the sys.resource_stats view and reviewing the active_session_count column.

クエリのパフォーマンスの監視Monitoring query performance

クエリが低速または実行時間が長いと、大量のシステム リソースが消費される可能性があります。Slow or long running queries can consume significant system resources. ここでは、動的管理ビューを使用して、いくつかの一般的なクエリ パフォーマンスの問題を検出する方法について説明します。This section demonstrates how to use dynamic management views to detect a few common query performance problems.

上位 N 個のクエリの検索Finding top N queries

次の例では、平均 CPU 時間の上位 5 個のクエリに関する情報を返します。The following example returns information about the top five queries ranked by average CPU time. この例では、論理的に等価なクエリがリソースの累計消費量ごとにグループ化されるように、クエリ ハッシュに応じてクエリを集計します。This example aggregates the queries according to their query hash, so that logically equivalent queries are grouped by their cumulative resource consumption.

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;

クエリのブロックの監視Monitoring blocked queries

クエリが低速または実行時間が長いと、大量のリソースが消費され、結果としてクエリがブロックされる可能性があります。Slow or long-running queries can contribute to excessive resource consumption and be the consequence of blocked queries. ブロックの原因には、不適切なアプリケーション設計、不適切なクエリ プラン、有効なインデックスの欠如などがあります。The cause of the blocking can be poor application design, bad query plans, the lack of useful indexes, and so on. sys.dm_tran_locks ビューを使用すると、データベースで現在ロックされているアクティビティに関する情報を取得することができます。You can use the sys.dm_tran_locks view to get information about the current locking activity in database. サンプル コードについては、「sys.dm_tran_locks (Transact-SQL)」を参照してください。For example code, see sys.dm_tran_locks (Transact-SQL). ブロッキングのトラブルシューティングの詳細については、Azure SQL のブロックの問題の概要と解決策に関するページを参照してください。For more information on troubleshooting blocking, see Understand and resolve Azure SQL blocking problems.

クエリ プランの監視Monitoring query plans

クエリ プランの効率が悪いと、CPU の消費量が増える可能性があります。An inefficient query plan also may increase CPU consumption. 次の例では、sys.dm_exec_query_stats ビューを使用して、累積 CPU 時間が最も多いクエリを特定します。The following example uses the sys.dm_exec_query_stats view to determine which query uses the most cumulative CPU.

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;

関連項目See also

Azure SQL Database と Azure SQL Managed Instance の概要Introduction to Azure SQL Database and Azure SQL Managed Instance