Dinamik yönetim görünümlerini kullanarak Microsoft Azure SQL Yönetilen Örneği performansını izleme

Şunlar için geçerlidir:Azure SQL Yönetilen Örneği

Microsoft Azure SQL Yönetilen Örneği, engellenen veya uzun süre çalışan sorgular, kaynak performans sorunları, zayıf sorgu planları vb. neden olabilecek performans sorunlarını tanılamak için dinamik yönetim görünümlerinin (DMV) bir alt kümesini etkinleştirir. Bu makalede, dinamik yönetim görünümlerini kullanarak yaygın performans sorunlarını algılama hakkında bilgi sağlanır.

Bu makale Azure SQL Yönetilen Örneği hakkındadır. Ayrıca bkz. Dinamik yönetim görünümlerini kullanarak performansı izleme Microsoft Azure SQL Veritabanı.

İzinler

Azure SQL Yönetilen Örneği dinamik yönetim görünümünü sorgulamak için VIEW SERVER STATE izinleri gerekir.

GRANT VIEW SERVER STATE TO database_user;

SQL Server örneğinde ve Azure SQL Yönetilen Örneği dinamik yönetim görünümleri sunucu durumu bilgilerini döndürür.

CPU performansı sorunlarını belirleme

CPU tüketimi uzun süreler için %80'in üzerindeyse aşağıdaki sorun giderme adımlarını göz önünde bulundurun:

CPU sorunu şu anda oluşuyor

Sorun şu anda oluşuyorsa iki olası senaryo vardır:

Yüksek CPU'ları birikmeli olarak kullanan tek tek sorguların çoğu

En çok kullanılan sorgu karmalarını tanımlamak için aşağıdaki sorguyu kullanın:

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 kullanan ve uzun süre çalışan sorgular hala çalışıyor

Bu sorguları tanımlamak için aşağıdaki sorguyu kullanın:

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 sorunu geçmişte oluştu

Sorun geçmişte oluştuysa ve kök neden analizi yapmak istiyorsanız Sorgu Deposu'nı kullanın. Veritabanı erişimi olan kullanıcılar Sorgu Deposu verilerini sorgulamak için T-SQL kullanabilir. Sorgu Deposu varsayılan yapılandırmaları 1 saatlik ayrıntı düzeyi kullanır. Yüksek CPU kullanan sorguların etkinliğine bakmak için aşağıdaki sorguyu kullanın. Bu sorgu en çok CPU kullanan 15 sorguyu döndürür. değiştirmeyi rsi.start_time >= DATEADD(hour, -2, GETUTCDATE()unutmayın:

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

Sorunlu sorguları tanımladıktan sonra, CPU kullanımını azaltmak için bu sorguları ayarlamanın zamanı geldi. Sorguları ayarlamak için zamannız yoksa, sorunu geçici olarak çözmek için yönetilen örneğin SLO'sunu yükseltmeyi de seçebilirsiniz.

GÇ performansı sorunlarını belirleme

GÇ performans sorunlarını belirlerken, GÇ sorunlarıyla ilişkilendirilmiş en önemli bekleme türleri şunlardır:

  • PAGEIOLATCH_*

    Veri dosyası GÇ sorunları için (, , PAGEIOLATCH_UPPAGEIOLATCH_EXdahilPAGEIOLATCH_SH). Bekleme türü adında varsa bir GÇ sorununa işaret eder. Sayfa mandal bekleme adında GÇ yoksa, farklı bir sorun türüne (örneğin, tempdb çekişme) işaret eder.

  • WRITE_LOG

    İşlem günlüğü GÇ sorunları için.

GÇ sorunu şu anda oluşuyorsa

ve wait_timeöğesini görmek wait_type için sys.dm_exec_requests veya sys.dm_os_waiting_tasks kullanın.

2. seçenek için, son iki saatlik izlenen etkinliği görüntülemek üzere arabellekle ilgili GÇ için Sorgu Deposu'na karşı aşağıdaki sorguyu kullanabilirsiniz:

-- 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 beklemeleri için toplam günlük GÇ'sini görüntüleme

Bekleme türü ise WRITELOG, deyimine göre toplam günlük GÇ'sini görüntülemek için aşağıdaki sorguyu kullanın:

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

Performans sorunlarını belirleme tempdb

GÇ performans sorunlarını tanımlarken, sorunlarla tempdb ilişkili en fazla bekleme türleri (değilPAGEIOLATCH_*) olur PAGELATCH_* . Ancak, PAGELATCH_* beklemeler her zaman çekişmeye sahip tempdb olduğunuz anlamına gelmez. Bu bekleme aynı veri sayfasını hedefleyen eşzamanlı isteklerden dolayı kullanıcı-nesne veri sayfası çekişmesiyle karşılaştığınızı gösteriyor da olabilir. Çakışmayı daha fazla onaylamak tempdb için sys.dm_exec_requests kullanarak wait_resource değerinin 2 tempdb ile başladığını2:x:y, veritabanı kimliği, x dosya kimliği ve y sayfa kimliği olduğunu onaylayın.

Çekişme için tempdb yaygın bir yöntem, kullanan tempdbuygulama kodunu azaltmak veya yeniden yazmaktır. Yaygın tempdb kullanım alanları şunlardır:

  • Geçici tablolar
  • Tablo değişkenleri
  • Tablo değerli parametreler
  • Sürüm deposu kullanımı (uzun süre çalışan işlemlerle ilişkili)
  • Sıralama, karma ile birleştirme ve biriktirici kullanan sorgu planlarına sahip sorgular

Tablo değişkenlerini ve geçici tabloları kullanan en önemli sorgular

Tablo değişkenlerini ve geçici tabloları kullanan en çok kullanılan sorguları belirlemek için aşağıdaki sorguyu kullanın:

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;

Uzun süre çalışan işlemleri tanımlama

Uzun süre çalışan işlemleri tanımlamak için aşağıdaki sorguyu kullanın. Uzun süre çalışan işlemler sürüm deposu temizlemesini engeller.

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;

Bellek verme bekleme performansı sorunlarını belirleme

En fazla bekleme türünüzse RESOURCE_SEMAHPORE ve yüksek CPU kullanımı sorununuz yoksa bellek verme bekleme sorununuz olabilir.

Beklemenin RESOURCE_SEMAHPORE en iyi bekleme olup olmadığını belirleme

Beklemenin en iyi bekleme olup olmadığını RESOURCE_SEMAHPORE belirlemek için aşağıdaki sorguyu kullanın

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;

Yüksek bellek tüketen deyimleri tanımlama

Yetersiz bellek hatalarıyla karşılaşırsanız sys.dm_os_out_of_memory_events içeriğini gözden geçirin.

Yüksek bellek tüketen deyimleri tanımlamak için aşağıdaki sorguyu kullanın:

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;

Bellek vermelerini tanımlama

İlk 10 etkin bellek iznini belirlemek için aşağıdaki sorguyu kullanın:

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;

Veritabanı ve nesne boyutlarını hesaplama

Aşağıdaki sorgu veritabanınızın boyutunu döndürür (megabayt cinsinden):

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

Aşağıdaki sorgu veritabanınızdaki tek tek nesnelerin boyutunu döndürür (megabayt cinsinden):

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

Bağlantıları izleme

Belirli bir yönetilen örneğe kurulan bağlantılarla ilgili bilgileri ve her bağlantının ayrıntılarını almak için sys.dm_exec_connections görünümünü kullanabilirsiniz. Ayrıca, sys.dm_exec_sessions görünümü tüm etkin kullanıcı bağlantıları ve iç görevler hakkında bilgi alınırken yararlıdır.

Aşağıdaki sorgu geçerli bağlantıyla ilgili bilgileri alır:

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;

Kaynak kullanımını izleme

Sql Server'da olduğu gibi Sorgu Deposu'nu kullanarak kaynak kullanımını izleyebilirsiniz.

Ayrıca sys.dm_db_resource_stats ve sys.server_resource_stats kullanarak kullanımı izleyebilirsiniz.

sys.dm_db_resource_stats

her veritabanında sys.dm_db_resource_stats görünümünü kullanabilirsiniz. Görünüm, sys.dm_db_resource_stats hizmet katmanına göre son kaynak kullanım verilerini gösterir. CPU, veri GÇ, günlük yazma işlemleri ve bellek için ortalama yüzdeler 15 saniyede bir kaydedilir ve 1 saat boyunca korunur.

Bu görünüm kaynak kullanımına daha ayrıntılı bir bakış sağladığından, önce geçerli durum çözümlemeleri veya sorun giderme işlemleri için kullanın sys.dm_db_resource_stats . Örneğin, bu sorgu son bir saat içindeki geçerli veritabanı için ortalama ve en yüksek kaynak kullanımını gösterir:

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;  

Diğer sorgular için sys.dm_db_resource_stats'deki örneklere bakın.

sys.server_resource_stats

bir Azure SQL Yönetilen Örneği CPU kullanımı, GÇ ve depolama verilerini döndürmek için sys.server_resource_stats kullanabilirsiniz. Veriler beş dakikalık aralıklarla toplanır ve toplanır. Her 15 saniyede bir raporlama için bir satır vardır. Döndürülen veriler CPU kullanımı, depolama boyutu, GÇ kullanımı ve yönetilen örnek SKU'sunu içerir. Geçmiş veriler yaklaşık 14 gün boyunca saklanır.

Örnekler, örneğinizin kaynakları nasıl kullandığı hakkında bilgi almak için katalog görünümünü kullanmanın sys.server_resource_stats farklı yollarını gösterir.

  1. Aşağıdaki örnek, son yedi gün içindeki ortalama CPU kullanımını döndürür:

    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. Aşağıdaki örnek, büyüme eğilimi analizine izin vermek için örneğiniz tarafından günde kullanılan ortalama depolama alanını döndürür:

    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
    

En fazla eşzamanlı istek sayısı

Geçerli eşzamanlı istek sayısını görmek için bu Transact-SQL sorgusunu veritabanınızda çalıştırın:

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

Tek bir veritabanının iş yükünü analiz etmek için, bu sorguyu analiz etmek istediğiniz veritabanına göre filtrelemek üzere değiştirin. Örneğin, adlı MyDatabasebir veritabanınız varsa, bu Transact-SQL sorgusu bu veritabanındaki eşzamanlı isteklerin sayısını döndürür:

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

Bu yalnızca tek bir zaman noktasındaki bir anlık görüntüdür. İş yükünüzü ve eşzamanlı istek gereksinimlerinizi daha iyi anlamak için zaman içinde birçok örnek toplamanız gerekir.

En fazla eşzamanlı oturum açma

Oturum açma sıklığı hakkında bir fikir edinmek için kullanıcı ve uygulama desenlerinizi analiz edebilirsiniz. Ayrıca, bu makalede ele aldığımız bu veya diğer sınırlara basmadığınızdan emin olmak için bir test ortamında gerçek dünya yüklerini çalıştırabilirsiniz. Eşzamanlı oturum açma sayılarını veya geçmişini gösterebilen tek bir sorgu veya dinamik yönetim görünümü (DMV) yoktur.

Birden çok istemci aynı bağlantı dizesi kullanıyorsa, hizmet her oturum açma kimliğini doğrular. Aynı kullanıcı adı ve parolayı kullanarak aynı anda 10 kullanıcı veritabanına bağlanırsa, 10 eşzamanlı oturum açma işlemi olur. Bu sınır yalnızca oturum açma ve kimlik doğrulaması süresi için geçerlidir. Aynı 10 kullanıcı veritabanına sırayla bağlanırsa, eş zamanlı oturum açma sayısı hiçbir zaman 1'den büyük olmaz.

En fazla oturum sayısı

Geçerli etkin oturum sayısını görmek için bu Transact-SQL sorgusunu veritabanınızda çalıştırın:

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

SQL Server iş yükünü analiz ediyorsanız, sorguyu belirli bir veritabanına odaklanacak şekilde değiştirin. Bu sorgu, veritabanını Azure'a taşımayı düşünüyorsanız veritabanı için olası oturum gereksinimlerini belirlemenize yardımcı olur.

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

Bu sorgular da belirli bir nokta sayısı döndürür. Zaman içinde birden çok örnek toplarsanız oturum kullanımınızı en iyi şekilde anlarsınız.

Sorgu performansını izleme

Yavaş veya uzun süre çalışan sorgular önemli sistem kaynaklarını tüketebilir. Bu bölümde, sık karşılaşılan birkaç sorgu performansı sorununu algılamak için dinamik yönetim görünümlerinin nasıl kullanılacağı gösterilmektedir.

En çok N sorgu bulma

Aşağıdaki örnek, ortalama CPU süresine göre sıralanan ilk beş sorgu hakkında bilgi döndürür. Bu örnek sorguları sorgu karmalarına göre toplayarak mantıksal olarak eşdeğer sorguların birikmeli kaynak tüketimine göre gruplandırılmış olmasını sağlar.

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;

Engellenen sorguları izleme

Yavaş veya uzun süre çalışan sorgular aşırı kaynak tüketimine katkıda bulunabilir ve engellenen sorguların sonucu olabilir. Engellemenin nedeni kötü uygulama tasarımı, hatalı sorgu planları, yararlı dizinlerin olmaması vb. olabilir. Veritabanındaki geçerli kilitleme etkinliği hakkında bilgi almak için sys.dm_tran_locks görünümünü kullanabilirsiniz. Örneğin kod, bkz . sys.dm_tran_locks. Engelleme sorunlarını giderme hakkında daha fazla bilgi için bkz . Azure SQL engelleme sorunlarını anlama ve çözme.

Kilitlenmeleri izleme

Bazı durumlarda, iki veya daha fazla sorgu birbirini karşılıklı olarak engelleyerek kilitlenmeye neden olabilir.

Kilitlenme olaylarını yakalamak için bir veritabanını izlemek için Genişletilmiş Olaylar oluşturabilir, ardından Sorgu Deposu'nda ilgili sorguları ve bunların yürütme planlarını bulabilirsiniz.

Azure SQL Yönetilen Örneği için Kilitlenmeler kılavuzundaki Kilitlenme araçlarınabakın.

Sorgu planlarını izleme

Verimsiz bir sorgu planı DA CPU tüketimini artırabilir. Aşağıdaki örnek, en kümülatif CPU'yu kullanan sorguyu belirlemek için sys.dm_exec_query_stats görünümünü kullanır.

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;

Diğer izleme seçenekleri

SQL Analizler ile izleme (önizleme)

Azure İzleyici SQL Analizler (önizleme), Azure SQL Yönetilen Örneği örneklerini, Azure SQL Veritabanı veritabanlarını ve Azure SQL VM'lerinde SQL Server'ı izlemeye yönelik bir araçtır. Bu hizmet, dinamik yönetim görünümlerinden (DMV’ler) verileri yakalamak için bir uzak aracı kullanır ve verileri izlenebileceği ve analiz edilebileceği Azure Log Analytics’e yönlendirir. Azure İzleyici'deki bu verileri sağlanan görünümlerde görüntüleyebilir veya sorguları çalıştırmak ve eğilimleri analiz etmek için günlük verilerine doğrudan erişebilirsiniz. Azure İzleyici SQL Analizler (önizleme) kullanmaya başlamak için bkz. SQL Analizler etkinleştirme (önizleme).

Azure İzleyici ile izleme

Azure İzleyici, izleme Azure SQL Yönetilen Örneği için çeşitli tanılama veri toplama grupları, ölçümler ve uç noktalar sağlar. Daha fazla bilgi için bkz. Azure İzleyici ile Azure SQL Yönetilen Örneği izleme. Azure SQL Analytics (önizleme), birçok izleme çözümünün artık etkin geliştirme aşamasında olmadığı Azure İzleyici ile tümleştirmedir. Daha fazla izleme seçeneği için bkz. Azure SQL Yönetilen Örneği ve Azure SQL Veritabanı'de izleme ve performans ayarlama.

Ayrıca bkz.

Sonraki adımlar