मैं इस एक्सटेंडेड इवेंट्स XML को जितनी जल्दी हो सके, कैसे हटा सकता हूं?


13

मैंने SQL Server 2008 R2 में एक विस्तारित ईवेंट सत्र बनाया। सत्र चलता है, और घटनाओं को इकट्ठा करता है जैसे वे होते हैं, ठीक वैसे ही जैसे आप अपेक्षा करते हैं।

अगर मैं अपेक्षाकृत कुछ घटनाओं के होने पर xml को काटता हूं, तो प्रदर्शन स्वीकार्य है। जब मेरे पास हजारों कार्यक्रम होते हैं, तो यह हमेशा के लिए xml को चूर कर देता है।

मुझे पता है कि मैं कुछ गलत कर रहा हूं, मुझे अभी यह समझने की जरूरत नहीं है कि XML इंजन के इंटर्नल के बारे में क्या समझा जाए।

यह मेरे विस्तारित घटनाक्रम सत्र की परिभाषा है:

IF EXISTS 
(
    SELECT 1 
    FROM sys.server_event_sessions dxs 
    WHERE dxs.name = 'queries'
)
BEGIN
    IF EXISTS (
        SELECT 1 
        FROM sys.dm_xe_sessions dxs 
        WHERE dxs.name = 'queries'
    )
    BEGIN
        ALTER EVENT SESSION queries ON SERVER STATE = STOP;
    END
    DROP EVENT SESSION queries ON SERVER;
END

CREATE EVENT SESSION queries ON SERVER 
ADD EVENT sqlserver.sql_statement_starting
(
    ACTION 
    (
        package0.collect_system_time
        --, package0.event_sequence
        , sqlserver.client_app_name
        , sqlserver.client_hostname
        --, sqlserver.database_name
        , sqlserver.plan_handle
        , sqlserver.sql_text
        , sqlserver.username
    )
    WHERE sqlserver.username = N'<some username>'
        AND sqlserver.database_id = 6 /* specific database */
        AND sqlserver.client_hostname <> '<my machine>'
) 
, ADD EVENT sqlserver.error_reported 
(
    ACTION 
    (
        package0.collect_system_time
        , sqlserver.client_app_name
        , sqlserver.client_hostname
        , sqlserver.plan_handle
        , sqlserver.sql_text
        , sqlserver.username
    )
    WHERE sqlserver.username <> N'<some username>'
        /* fluff errors below */
        AND error <> 5703 /* Changed language setting to %.*ls. */
        AND error <> 5701 /* Changed database context to '%.*ls'. */
        AND error <> 2528 /* DBCC execution completed. If DBCC printed error messages, contact your system administrator. */
        AND error <> 7969 /* No active open transactions. */
        --AND error <> 14205/* (unknown) */
        AND error <> 4035 /* Processed %I64d pages for database '%ls', file '%ls' on file %d. */
        AND error <> 18265/* Log was backed up. Database: %s, creation date(time): %s(%s), first LSN: %s, last LSN: %s, number of dump devices: %d, device information: (%s). This is an informational message only. No user action is required. */
        AND error <> 3014 /* %hs successfully processed %I64d pages in %d.%03d seconds (%d.%03d MB/sec). */
        AND error <> 14570/* (Job outcome) */
        AND error <> 8153 /* Warning: Null value is eliminated by an aggregate or other SET operation. */

)
ADD TARGET package0.ring_buffer
(
    SET max_memory = 102400
)
WITH 
(
    STARTUP_STATE=OFF
    , TRACK_CAUSALITY = ON
);
GO

IF EXISTS 
(
    SELECT 1 
    FROM sys.server_event_sessions dxs 
    WHERE dxs.name = 'queries'
)
BEGIN
    ALTER EVENT SESSION queries ON SERVER STATE = START;
END

इस तरह से मैं परिणामों को काट रहा हूँ:

/***************************

shred the Event Data into readable form

***************************/

DECLARE @xml XML;

SELECT TOP(1) @xml = CONVERT(xml, xet.target_data)
FROM sys.dm_xe_session_targets AS xet
    INNER JOIN sys.dm_xe_sessions AS xe ON (xe.address = xet.event_session_address)
WHERE xe.name = 'queries';

SELECT t.EventName
    , DateStamp = DATEADD(HOUR, -6, t.EventDateStamp)
    , DatabaseName = d.name
    , t.ErrorNumber
    , t.ErrorSeverity
    , t.ErrorState
    , t.ErrorMessage
    , t.CollectSystemTime
    , t.ClientAppName
    , t.ClientHostName
    , t.PlanHandle
    , t.SqlText
    , t.UserName
FROM (
        SELECT EventName = s.value('(@name)[1]','varchar(500)')
            , EventDateStamp = s.value('(@timestamp)[1]','datetime')
            , DatabaseID = s.value('(data[(@name)[1] eq "source_database_id"]/value/text())[1]','varchar(255)')
            , ErrorNumber = s.value('(data[(@name)[1] eq "error"]/value/text())[1]','int')
            , ErrorSeverity = s.value('(data[(@name)[1] eq "severity"]/value/text())[1]','int')
            , ErrorState = s.value('(data[(@name)[1] eq "state"]/value/text())[1]','int')
            , ErrorMessage = s.value('(data[(@name)[1] eq "message"]/value/text())[1]','varchar(255)')
            , CollectSystemTime = s.value('(action[(@name)[1] eq "collect_system_time"]/text/text())[1]','varchar(255)')
            , ClientAppName = s.value('(action[(@name)[1] eq "client_app_name"]/value/text())[1]','varchar(255)')
            , ClientHostName = s.value('(action[(@name)[1] eq "client_hostname"]/value/text())[1]','varchar(255)')
            , PlanHandle = CONVERT(xml, s.value('(action[(@name)[1] eq "plan_handle"]/value/text())[1]','varchar(255)')).value('(plan/@handle)[1]', 'varchar(255)')
            , SqlText = s.value('(action[(@name)[1] eq "sql_text"]/value/text())[1]','nvarchar(max)')
            , UserName = s.value('(action[(@name)[1] eq "username"]/value/text())[1]','varchar(128)')
        FROM @xml.nodes('/RingBufferTarget/event') AS xm(s)
    ) t
    LEFT JOIN sys.databases d ON t.DatabaseID = d.database_id
ORDER BY t.UserName
    , t.EventDateStamp;

2
आपने देखा है इस भले ही यह नवीनतम संस्करण के लिए है?
टॉम वी -

1
मुझे पता है कि यह आपकी मदद नहीं करेगा, लेकिन, मेरी राय में, XML श्रेडिंग आपके महंगे कोर लाइसेंस का उपयोग करने का सबसे खराब तरीका है। क्या पॉवरशेल के साथ बाहरी रूप से कतरन एक संभावना है?
spaghettidba


1
बस एक त्वरित बिंदु के रूप में: IBM के DB2.directly XML को BLOBs (पाठ) के रूप में समर्थन करता है, जैसा कि संबंधपरक तालिकाओं में कटा हुआ है, या एक पूर्ण अनुकूलित देशी-XML डेटा मॉडल के रूप में है। (मैंने बताया कि जब उन्होंने उस अंतिम, प्योरएक्सएमएल समर्थन को जोड़ा, तो वे नाम को अंततः डीबी 3 में बदलने के बहुत करीब आ गए; यह माना जाता था कि प्रमुख एक अग्रिम है।) - दावाकर्ता: मेरे पास प्योरएक्सएमएल के डिजाइन पर कुछ प्रभाव था। , हालांकि मैं उस परियोजना पर काम नहीं कर रहा था, और मैं अभी भी आईबीएम के साथ हूं।
केशालम

1
@MaxVernon - और OPTION (Optimize FOR (@xml = Null))आप के बारे में भी OPTION (QUERYTRACEON 4130 stackoverflow.com/a/3979266/73226
मार्टिन स्मिथ

जवाबों:


11

इस ब्लॉग पोस्ट की पहचान के लिए @Tom V का धन्यवाद जो एक अस्थायी तालिका की आवश्यकता की पहचान करता है।

ब्लॉग पोस्ट में विचारों को अपनाना, यह अब बहुत जल्दी काम करता है:

/***************************

shred the Event Data into readable form

***************************/

DECLARE @xml XML;

SELECT TOP(1) @xml = CONVERT(xml, xet.target_data)
FROM sys.dm_xe_session_targets AS xet
    INNER JOIN sys.dm_xe_sessions AS xe ON (xe.address = xet.event_session_address)
WHERE xe.name = 'queries';

IF OBJECT_ID('tempdb..#xmlResults') IS NOT NULL
DROP TABLE #xmlResults;

CREATE TABLE #xmlResults
(
    RowNum INT NOT NULL
        PRIMARY KEY CLUSTERED
        IDENTITY(1,1)
    , xeXML XML NOT NULL
);

INSERT INTO #xmlResults (xeXML)
SELECT xm.s.query('.')
FROM @xml.nodes('/RingBufferTarget/event') AS xm(s)
OPTION (Optimize FOR (@xml = Null)); -- Useful for SQL 2008

SELECT *
FROM #xmlResults

SELECT t.EventName
    , DateStamp = DATEADD(HOUR, -6, t.EventDateStamp)
    , DatabaseName = d.name
    , t.ErrorNumber
    , t.ErrorSeverity
    , t.ErrorState
    , t.ErrorMessage
    , t.CollectSystemTime
    , t.ClientAppName
    , t.ClientHostName
    , t.PlanHandle
    , t.SqlText
    , t.UserName
FROM (
        SELECT EventName =          xeXML.value('(event/@name)[1]','varchar(500)')
            , EventDateStamp =      xeXML.value('(event/@timestamp)[1]','datetime')
            , DatabaseID =          xeXML.value('(event/data[(@name)[1] eq "source_database_id"]/value/text())[1]','varchar(255)')
            , ErrorNumber =         xeXML.value('(event/data[(@name)[1] eq "error"]/value/text())[1]','varchar(255)')
            , ErrorSeverity =       xeXML.value('(event/data[(@name)[1] eq "severity"]/value/text())[1]','varchar(255)')
            , ErrorState =          xeXML.value('(event/data[(@name)[1] eq "state"]/value/text())[1]','varchar(255)')
            , ErrorMessage =        xeXML.value('(event/data[(@name)[1] eq "message"]/value/text())[1]','varchar(255)')
            , CollectSystemTime =   xeXML.value('(event/action[(@name)[1] eq "collect_system_time"]/text/text())[1]','varchar(255)')
            , ClientAppName =       xeXML.value('(event/action[(@name)[1] eq "client_app_name"]/value/text())[1]','varchar(255)')
            , ClientHostName =      xeXML.value('(event/action[(@name)[1] eq "client_hostname"]/value/text())[1]','varchar(255)')
            , PlanHandle = CONVERT(xml, xeXML.value('(event/action[(@name)[1] eq "plan_handle"]/value/text())[1]','varchar(255)')).value('(plan/@handle)[1]', 'varchar(255)')
            , SqlText =             xeXML.value('(event/action[(@name)[1] eq "sql_text"]/value/text())[1]','nvarchar(max)')
            , UserName =            xeXML.value('(event/action[(@name)[1] eq "username"]/value/text())[1]','varchar(128)')
        FROM #xmlResults xm
    ) t
    LEFT JOIN sys.databases d ON t.DatabaseID = d.database_id
ORDER BY t.UserName
    , t.EventDateStamp;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.