Поиск объектов, на которые наложено наибольшее число блокировок

Область применения:SQL ServerAzure SQL Database

Администраторам баз данных часто нужно определить источник блокировок, приводящих к ухудшению производительности базы данных.

Например, наблюдение за рабочим сервером осуществляется с целью выявления возможных узких мест. Имеется предположение о наличии высоко востребованных ресурсов, поэтому требуется определить количество блокировок этих объектов. Как только объекты с наибольшим количеством блокировок будут определены, можно будет предпринять действия по оптимизации доступа к этим востребованным объектам.

Для этого используйте редактор запросов в СРЕДЕ SQL Server Management Studio.

Поиск объектов с наибольшим количеством блокировок

  1. В редакторе запросов выполните следующие инструкции.

    -- Find objects in a particular database that have the most
    -- lock acquired. This sample uses AdventureWorksDW2022.
    -- Create the session and add an event and target.
    
    IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='LockCounts')
        DROP EVENT session LockCounts ON SERVER;
    GO
    DECLARE @dbid int;
    
    SELECT @dbid = db_id('AdventureWorksDW2022');
    
    DECLARE @sql nvarchar(1024);
    SET @sql = '
        CREATE event session LockCounts ON SERVER
            ADD EVENT sqlserver.lock_acquired (WHERE database_id ='
                + CAST(@dbid AS nvarchar) +')
            ADD TARGET package0.histogram(
                SET filtering_event_name=''sqlserver.lock_acquired'',
                    source_type=0, source=''resource_0'')';
    
    EXEC (@sql);
    GO
    ALTER EVENT session LockCounts ON SERVER
        STATE=start;
    GO
    -- Create a simple workload that takes locks.
    
    USE AdventureWorksDW2022;
    GO
    SELECT TOP 1 * FROM dbo.vAssocSeqLineItems;
    GO
    -- The histogram target output is available from the
    -- sys.dm_xe_session_targets dynamic management view in
    -- XML format.
    -- The following query joins the bucketizing target output with
    -- sys.objects to obtain the object names.
    
    SELECT name, object_id, lock_count
        FROM
        (
        SELECT objstats.value('.','bigint') AS lobject_id,
            objstats.value('@count', 'bigint') AS lock_count
            FROM (
                SELECT CAST(xest.target_data AS XML)
                    LockData
                FROM     sys.dm_xe_session_targets xest
                    JOIN sys.dm_xe_sessions        xes  ON xes.address = xest.event_session_address
                    JOIN sys.server_event_sessions ses  ON xes.name    = ses.name
                WHERE xest.target_name = 'histogram' AND xes.name = 'LockCounts'
                 ) Locks
            CROSS APPLY LockData.nodes('//HistogramTarget/Slot') AS T(objstats)
        ) LockedObjects
        INNER JOIN sys.objects o  ON LockedObjects.lobject_id = o.object_id
        WHERE o.type != 'S' AND o.type = 'U'
        ORDER BY lock_count desc;
    GO
    
    -- Stop the event session.
    
    ALTER EVENT SESSION LockCounts ON SERVER
        state=stop;
    GO
    

Заметка

Предыдущий пример кода Transact-SQL выполняется в локальной среде SQL Server, но может не работать в базе данных SQL Azure. Основные части примера, непосредственно связанные с событиями, например ADD EVENT sqlserver.lock_acquired работа с базой данных SQL Azure. Тем не менее, для выполнения этого примера необходимо заменить предварительные элементы, такие как sys.server_event_sessions, на их аналоги из базы данных SQL Azure, например sys.database_event_sessions. Дополнительные сведения об этих незначительных различиях между локальным экземпляром SQL Server и базой данных SQL Azure см. в следующих статьях:

После выполнения инструкций показанного выше скрипта Transact-SQL на вкладке Результаты редактора запросов будут отображены следующие столбцы:

  • name
  • object_id
  • lock_count

См. также

CREATE EVENT SESSION (Transact-SQL)
ALTER EVENT SESSION (Transact-SQL)
sys.dm_xe_session_targets (Transact-SQL)
sys.dm_xe_sessions (Transact-SQL)
sys.server_event_sessions (Transact-SQL)