Während der Abfrageausführung erlangte Sperren anzeigen (SQL Server)

12

Der Ausführungsplan für Abfragen zeigt standardmäßig keine Sperrdetails an. Ist es möglich, die Sperren zusammen mit dem Typ anzuzeigen, der während der Ausführung einer Abfrage erfasst wurde?

Faisal Mansoor
quelle

Antworten:

14

Ist es möglich, die Sperren zusammen mit dem Typ anzuzeigen, der während der Ausführung einer Abfrage erworben wurde?

Ja, um Sperren zu bestimmen,

  1. Sie können beta_lockinfovon Erland Sommarskog verwenden

    beta_lockinfoist eine gespeicherte Prozedur, die Informationen zu Prozessen und deren Sperren sowie zu den aktiven Transaktionen bereitstellt. beta_lockinfowurde entwickelt, um so viele Informationen wie möglich über eine Blockierungssituation zu sammeln, damit Sie den Täter sofort finden und den Blockierungsprozess beenden können, wenn die Situation verzweifelt ist. Anschließend können Sie sich zurücklehnen und die Ausgabe von analysieren, um beta_lockinfozu verstehen, wie die Blockierungssituation entstanden ist, und herauszufinden, welche Maßnahmen ergriffen werden müssen, um ein erneutes Auftreten der Situation zu verhindern. Die Ausgabe von beta_lockinfozeigt alle aktiven und passiven Prozesse mit Sperren an, welche Objekte sie sperren, welchen Befehl sie zuletzt übergeben haben und welche Anweisung sie ausführen. Sie erhalten auch die Abfragepläne für die aktuellen Anweisungen. Normalerweise rennst dubeta_lockinfo , um die Ausgabe direkt anzuzeigen. Es gibt jedoch auch einen Archivierungsmodus, in dem die Daten in einer Tabelle gespeichert werden. Dies ist nicht zuletzt nützlich, wenn Sie möchten, dass Ihnen jemand die Ausgabe von beta_lockinfoeiner Site sendet, auf die Sie keinen Zugriff haben.

  2. Eine andere Methode ist die sp_whoIsActivevon Adam Machanic mit@get_locks = 1

    EXEC sp_WhoIsActive 
    @filter = '', 
    @filter_type = 'session', 
    @not_filter = '', 
    @not_filter_type = 'session', 
    @show_own_spid = 0, 
    @show_system_spids = 0, 
    @show_sleeping_spids = 1, 
    @get_full_inner_text = 0, 
    @get_plans = 1, 
    @get_outer_command = 1, 
    @get_transaction_info = 0, 
    @get_task_info = 1, 
    @get_locks = 1,   ----------> 1 = ON (get lock info); 0 = OFF
    @get_avg_time = 0, 
    @get_additional_info = 0, 
    @find_block_leaders = 0, 
    @delta_interval = 0, 
    @output_column_list = '[dd%][session_id][sql_text][sql_command][login_name][wait_info][tasks][tran_log%][cpu%][temp%][block%][reads%][writes%][context%][physical%][query_plan][locks][%]', 
    @sort_order = '[start_time] ASC', 
    @format_output = 1, 
    @destination_table = '', 
    @return_schema = 0, 
    @schema = NULL, 
    @help = 0
Kin Shah
quelle
danke, die oben gespeicherten procs eignen sich hervorragend für db admin-szenarien, aber kennen sie alternative szenarien für die abfrageoptimierung? Ich versuche, das Sperrverhalten einer Einfügeabfrage in der Entwicklungsumgebung zu verstehen (die nicht viele Daten enthält, daher wird die Abfrage nicht sehr lange ausgeführt). Ich möchte alle Sperren sehen, die eine Abfrage nach ihrer Ausführung erhalten hat. Ich möchte den Sperrplan sehen, ähnlich wie der Abfrageplan funktioniert.
Faisal Mansoor
1
Da Sie SQL Server 2012 verwenden, sollten Sie sich auf Abfrage-Granularebene mit XEvents - Bestimmen, welche Abfragen Sperren enthalten, befassen . Dies gibt Ihnen einen guten Start.
Kin Shah
4

So betrachte ich Sperren nach Prozess / Tabelle / Sperrentyp:

SELECT 
    HostName,
    "OS UserName",
    Login, 
    spid, 
    "Database", 
    TableID,
    "Table Name_________", 
    IndID, 
--  [Index Name],
    "Lock Type", 
    "Lock Mode", 
    Status, 
--  Resource,
    Count(*) AS "Lock Count"
FROM (
    SELECT
        Convert(VarChar(30), RTRIM(P.HostName)) AS HostName,
        Convert(VarChar(30), RTRIM(P.nt_UserName)) AS "OS UserName",
        Convert(VarChar(30), Suser_SName(p.sid)) AS Login, 
        Convert(SmallInt, req_spid) AS spid,
        Convert(VarChar(30), DB_Name(rsc_dbid)) AS "Database",
        rsc_objid AS TableID,
    Convert(VarChar(30), Object_Name(rsc_objid, rsc_dbid))
        AS [Table Name_________],
        rsc_indid AS IndID, 
        CASE SubString (lock_type.name, 1, 4) 
            When '' Then 'None'
            When 'DB' Then 'Database'
            When 'FIL' Then 'File'
            When 'IDX' Then 'Index'
            When 'TAB' Then 'Table'
            When 'PAG' Then 'Page'
            When 'KEY' Then 'Key'
            When 'EXT' Then 'Extent'
            When 'RID' Then 'Row ID'
            When 'APP' Then 'Application'
            Else SubString (lock_type.name, 1, 4)
        END AS "Lock Type",
        Case SubString (lock_mode.name, 1, 12)
            When NULL Then 'N/A'
            When 'Sch-S' Then 'SCHEMA (Stability)'--'SCHEMA stability lock'
            When 'Sch-M' Then 'SCHEMA (Modification)'--'SCHEMA modification lock'
            When 'S' Then 'SHARED'--'SHARED Lock acquisition'
            When 'U' Then 'UPDATE'--'UPDATE lock acquisition'
            When 'X' Then 'EXCLUSIVE'--'EXCLUSIVE lock granted'
            When 'IS' Then 'SHARED (Intent)'--'INTENT for SHARED lock'
            When 'IU' Then 'UPDATE (Intent)'--'INTENT for UPDATE lock'
            When 'IX' Then 'EXCLUSIVE (Intent)'--'INTENT for EXCLUSIVE lock'
            When 'SIU' Then 'SHARED (Intent UPDATE)'--'SHARED lock with INTENT for UPDATE'
            When 'SIX' Then 'SHARED (Intent EXCLUSIVE)'--'SHARED lock with INTENT for EXCLUSIVE'
            When 'UIX' Then 'UPDATE'--'UPDATE lock with INTENT for EXCLUSIVE'
            When 'BU' Then 'UPDATE (BULK)'--'BULK UPDATE lock'
            Else SubString (lock_mode.name, 1, 12)
        END AS "Lock Mode", 
        SubString(lock_status.name, 1, 5) AS Status,
        SubString (rsc_text, 1, 16) AS Resource
    FROM 
        Master..SysLockInfo S
        JOIN Master..spt_values lock_type on S.rsc_type = lock_type.number
        JOIN Master..spt_values lock_status on S.req_status = lock_status.number
        JOIN Master..spt_values lock_mode on S.req_mode = lock_mode.number -1
        JOIN Master..SysProcesses P on S.req_spid = P.spid
    WHERE
            lock_type.type = 'LR'
        AND lock_status.type = 'LS'
        AND lock_mode.type = 'L'
        AND DB_Name(rsc_dbid) NOT IN ('master', 'msdb', 'model')
    ) AS X
WHERE TableID > 0
GROUP BY 
    HostName,
    "OS UserName",
    Login, 
    spid, 
    "Database", 
    TableID,
    "Table Name_________", 
    IndID, 
    "Lock Type", 
    "Lock Mode", 
    Status
ORDER BY
    spid, "Database", "Table Name_________", "Lock Type", Login
Shane Estelle
quelle
3
Es ist eine großartige Antwort und es ist so schade, dass Kompatibilitätsansichten verwendet werden. Komm schon, es ist 2015!
Spaghettidba
3

Sie können den Verlauf der erfassten Sperren auf der Registerkarte "Nachrichten" anzeigen, nachdem Sie Folgendes ausgeführt haben: DBCC TRACEON (1200, 3604, -1) Aber ACHTUNG, Sie aktivieren diese Ablaufverfolgungsflags GLOBAL. Vergessen Sie nicht, sie zu deaktivieren, sobald Sie dies nicht tun brauche sie.

Vedran
quelle
1

Sie können die Sperren für eine Sitzung mit sp_lock oder sys.dm_tran_locks anzeigen. In beiden Fällen können Sie nach Sitzung filtern. Sie können dazu auch Extended Events verwenden.

Matan Yungman
quelle
0

Ja, Sie können die Sperren und ihren Typ während der Ausführung der Abfrage über anzeigen

  1. Adam Mechanics SP_whoisactive Klicken Sie hier, um anzuzeigen

  2. Außerdem können Sie mit Hilfe von trace einen Blockbericht erstellen, wie hier erläutert

KASQLDBA
quelle
1
performance countersGibt Ihnen nur ein instanzweites Verhalten. Das OP will auf Abfrageebene.
Kin Shah
@ Kin, danke, gerade die zusätzlichen Informationen entfernt :)
KASQLDBA