Profiler: Why do you collect so much data?

This has been always been a classic Catch-22. Should I include that event? But that will bloat my profiler trace size very quickly!! And then suddenly, either your gut feeling takes over and you take a split second decision or you make the same decision again based on your SQL knowledge (+gut feeling) to include or not include that event. The decision is always between collecting too much data at the cost of degrading server performance further or collecting too less data that you would require another round of data collection to figure out the root cause of the performance issue that you are troubleshooting.

At the outset, let me make it clear that I am not *perfect* at configuring a profiler trace for every performance issue that you face. But I will say this that I have handled enough SQL performance issues and looked at profiler traces (I actually do this to earn a living Winking smile)  to help outline a set of DOs and DON’Ts for capturing profiler traces for diagnosing performance issues.

In this post, I shall outline some Profiler event categories and events which generate a plethora of noise more than anything else. These events are required for troubleshooting some very specific scenarios (which is why they were introduced) and can be done away with when you are capturing data for evaluating general server performance or looking to identify the resource consuming queries on your instance.

High frequency event categories

  • Broker – None of the events in the Broker Category are required unless you are troubleshooting an issue related to Database Mail or Service Broker in SQL Server 2005 or above. However, the Broker event category can generate a lot of noise if you have Service Broker/Database Mail configured on the server and are using it heavily.
  • Cursors – If the client application or provider that connects to your SQL Server instance uses Server Side cursors, then this event category can basically lead to an unmanageable amount of data collected which will take you ages to sift through. The sp_cursor* calls will be captured either ways in your Stored Procedure event classes which makes it moot point to track Cursor: Open, Close, Execute through this event category for general performance issues. The only useful events in this event category are CursorImplicitConversion (which lets you track Implicit Conversion of requested non-supported cursor type by the SQL engine) and CursorRecompile (which helps you track down T-SQL cursor recompiles due to schema changes).
  • Locks – Now this event category is a whale if you want my frank opinion. Lock:Acquired and Lock:Released event classes (if captured), can make your data analysis more difficult than scaling Mt. Everest! If you need to track the number of locks for each session, then it is done best outside the profiler using DMVs like sys.dm_tran_locks. However, this event category has some useful event classes like:
    1. Lock: Deadlock and Lock: Deadlock Chain – Helps a lot when troubleshooting deadlock issues
    2. Lock: Timeout and Lock: Timeout (timeout > 0) – Helps troubleshooting timeout related issues due to lock blocking.
    3. Lock: Escalation – This one is debatable. Helps track down Lock Escalations but on servers where there are high number of Lock Escalations, this can become a high frequency event.
  • OLEDB – Unless you know based on the symptoms seen regarding the issue that OLEDB calls need to be traced, you shouldn’t be collecting any event from this Event category except for OLEDB Errors. So if your OLEDB provider was returning a large number of errors, you would be able to track it down using the HRESULT obtained from this event class.
  • Query Notifications – Again the same logic mentioned above for Broker event category applies to Query Notifications event category too.
  • Scans – Now this might be useful when you are doing a repro of sorts on a test or development environment but on a production server this is a strict NO-NO! You really should be able to figure out looking at the plans whether there was a table/index scan without having to capture a separate noisy event in the profiler traces.
  • Security Audit – A very good event category when troubleshooting security or permissions related issues on a SQL instance. For Performance related issues, this is just plain *noise*! Because the events under this category are fired nineteen-to-the-dozen on a SQL instance and this would just bloat your profiler trace size rather than doing anything useful! The two really and I mean really useful events in this category are Audit: Login and Audit: Logout which help track the session’s connection settings and other attributes like host name, user name etc.
  • Transactions – This event category also has a lot of noise events which would aid in bloating profiler trace size rather than doing anything useful. Especially the Transaction Manager (TM:*) event classes are not to be captured unless you are troubleshooting an issue Begin/Commit/Rollback taking a long time to complete. The SQLTransation event is quite useful for troubleshooting Deadlock related issues as it helps track transaction begin and commit/rollback and nest levels for a particular session. The DTCTransaction event class is useful for troubleshooting DTC Transaction related issues and tracking the different states of a DTC transaction.
  • Performance Event Category – This is one of the most widely used event categories in CSS for troubleshooting query performance  issues. The reason for that is this event category helps you capture Query Plans. There are a bunch of different event classes in this category which helps you capture query plans which I shall divide into two classes based on data to be obtained from these events:
    1. Compile time details: Showplan All, Showplan XML & Showplan Text (occurs during query execution but doesn’t contain run-time details like rows returned) and Showplan XML For Query Compile & Showplan All For Query Compile (show you the compile time query plan). This event can be very useful when you want to capture a query plan for timeout related issues as the other events which show you the execution time query plans may not be generated when you are dealing with query timeouts. So if you are not facing any timeouts and need the query plans with run-time details, you need not capture any of the events mentioned above. The Query Compile event classes (especially the XML event) are required when you trying to nail down compilation related issues and want to find out the resources (CPU/Memory) consumed during query compilation.
    2. Run-time details: Showplan Statistics Profile and Showplan XML Statistics Profile show you the the query plan with run-time details in text and XML formats respectively. Based on what you like sifting through Text or XML, you could capture either one. XML events are not the best when it comes to toning down the size of the profiler traces captured.

    There are some other high frequency event classes which are mentioned below:

    1. SP:CacheMiss, SP:CacheInsert, SP:CacheRemove, SP:CacheHit – These events are helpful when tracking procedure cache plan caching issues but if you are not dealing with a specific issue related to Procedure Cache, then you are going to be dealing with a lot of noise in the profiler traces if these events are captured.
    2. TSQL : Prepare SQL, TSQL : Exec Prepared SQL, TSQL : Unprepare SQL – Useful for troubleshooting specific server side cursor calls but otherwise plain noise and should be avoided.

    image*TIP: Always check the “Show all Columns” option in the Profiler UI when configuring the trace as some of the event data columns capture valuable information about event which is essential to troubleshooting a performance issue like ObjectID, ObjectName etc.

    The events to be captured using SQL Profiler for common issues like High CPU usage, excessive I/O, timeouts etc. will be covered through a series of posts later.

    To summarize, the profiler can be a friendly tool when run using a Server Side trace with the right set of events being captured.

    How to create a Profiler Trace during Server startup

    I think I answered this question more than once on multiple different forums. So, I thought it was time to create a blog post on it.   

    One of my previous post has the steps to create a .sql file containing the server side trace definition. Once you have the .sql file generated by the SQL Profiler Trace GUI. Use the script to convert that into the stored procedure with the following changes:   

    declare @tracefilename nvarchar(255) 
    
    set @tracefilename = N'D:\StartupTrace'+CAST(DATEPART(d,GETDATE()) AS varchar(2))+CAST(DATEPART(M,GETDATE()) AS varchar(2))+CAST(DATEPART(YYYY,GETDATE()) AS varchar(4))+CAST(DATEPART(HH,GETDATE()) AS varchar(2))+CAST(DATEPART(MI,GETDATE()) AS varchar(2)) 
    
    exec @rc = sp_trace_create @TraceID output, 0, @tracefilename, @maxfilesize, NULL

    You will have to add the lines highlighted above and the make a change for the trace file name in the line that is not highlighted. This will ensure that every time your SQL instance starts up, you have a unique trace file name. If the filename is not unique, then the second time the service restarts you will get a trace creation error stating that the file already exists. You will see the following error in your SQL Errorlog:   

    Launched startup procedure ‘usp_startup_trace’.

    Windows error occurred while running SP_TRACE_CREATE. Error = 0x80070050(The file exists.).

    Error: 19062, Severity: 16, State: 1.Could not create a trace file. 

    After this is done, create the stored procedure to create the trace definition. Let’s say the proc name was “usp_startup_trace”.   

    Now, you will need to mark this stored procedure as a startup procedure using the following:

    EXEC sp_procoption 'usp_startup_trace','startup',true

     Once that is done, you will need to set the configuration options for the instance to scan for startup procedures. The default is set to 0.   

    EXEC sp_configure 'scan for startup procs',1 RECONFIGURE

     When your SQL instance restarts the next time a new file will be created for the profiler trace and sys.traces will show you new trace active on the server.  

    Reference: sp_procoption

    Initial Data Collection Script

    Where would you be able to use it?

    The cases where you can use this script effectively are:

    1. Performance issues where a quick initial look at the general state of the server is very valuable.

    2. Situations where issue is actually happening right now. However, that said, it is always good to collect post mortem data as well for further diagnostics. Performance Dashboard is a good option here but if you want a snapshot of the server and store it somewhere, then this script can help you.

    3. Situations where the problem is happening and you need to quickly verify that you are not hitting some known issues.

    How is this different from the other scripts that are already existing?

    There are scripts already out there which do the same thing. The advantage here is the fact that the output is in HTML format with bookmarks which makes it easy to determine what information is available. Also, it is easy to get to the sections that are of interest in the current scenario.

    Usage

    1. Download the script using the link given at the bottom of the page and save it to a file named INITIAL_DIAG.SQL. Open the script file in a SSMS Query Window.
    2. Press CTRL+SHIFT+F so that the output results are put into a file. Doing this will not produce a message or any other notification.
    3. Execute the script and specify INITIAL_DIAG.html as the output file name so that we can get the output in the require HTML format.

    Sample Output

    ********************************************************************************************
    INITIAL MICROSOFT PSS DATA COLLECTION
    ********************************************************************************************

    INDEX
    1. General Server Configuration
    a. Server Info
    b. Non-default sp_configure settings
    c. Server Settings
    d. Active Trace Flags
    e. Profiler Trace Information
    2. Memory Diagnostics
    a.DBCC MEMORYSTATUS output
    b.Memory Clerks rollup output
    3.Procedure Cache Statistics
    4.Database Diagnostics
    a.Replicated Databases
    b.Database File Usage Stats
    c.Index Statistics
    d.sp_helpdb output
    e.DBCC SQLPERF (LOGSPACE)
    f.Hypothetical Indexes
    5.Missing Indexes report
    6.Blocking Information
    7.Batch/Query Statistics

    ########################################

    ****************** SERVER INFO *********
    ########################################

    —————————————————————–
    Microsoft SQL Server 2005 – 9.00.3257.00 (X64)
    Jun 12 2008 16:47:07
    Copyright (c) 1988-2005 Microsoft Corporation
    Developer Edition (64-bit) on Windows NT 6.0 (Build 6001: Service Pack 1)

    —————————————————————
    SQL SERVER NAME: SERVER1

    CLUSTERED: No

    MACHINE NAME: SERVER1
    NET BIOS NAME: SERVER1

    SQL PID: 5076
    FTS Installed: YES
    Security Mode: MIXED
    Current SPID: 51

    Click here to download the script.

    Modification: June 20, 2012: Added additional code to account for the following:

    • Added code to identify read-write workload ratios
    • Added code to find out non-Microsoft DLLs loaded in SQL address space using sys.dm_os_loaded_modules
    • Added code to get output for SQL Server 2012 instances

    Collecting Server Side Profiler Traces

    When we want to monitor the kind of queries that hit across your SQL Server, most of us set up a Profiler Trace. But what most of us are not aware of is that there are two ways to setup a Profiler trace:

    1. A GUI based Profiler trace

    2. A Server side Profiler trace

    A GUI based profiler trace causes a performance impact on the server as high as 25% depending on the events being captured. So if you are monitoring SQL Server with the help of profiler traces on a long term basis then it would always be advisable to setup a server side profiler trace.

    Steps to setup a Server side Profiler Trace
    1. Create a Profiler Trace using the GUI and then script out the trace to a file called say sql_trace.sql. Open the SQL_TRACE.SQL file in query analyzer/management studio query window and make the following changes

    2. In the line “exec @rc = sp_trace_create @TraceID output, 2, N'<save location of trace file>’, @maxfilesize, NULL”, change the location where you want to store the trace file.

    3. Make sure @maxfilesize parameter is set to 350 or a desirable size. (This makes sure that you roll over to the next trace file once the current size hits 350 MB)

    4. Execute the script to create the trace. This will generate a Trace ID. The trace information can be obtained from fn_trace_getinfo function

    5. To stop the trace, use sp_trace_setstatus ,0

    6. To close the specified trace and delete its definition from the server us sp_trace_setstatus ,2

    The events that you had configured while in the GUI would be present in the generated script and will be set using the Stored Prodecure sp_trace_setevent.

    Remember that server side traces shouldn’t be writing to the same disk on which the SQL files are residing on and your profiler traces shouldn’t be writing to network drives/mapped drives or any other UNC shares. The destination file location should be a local disk. These are some recommendations that you need to keep in mind when configuring a server side profiler trace.

    Useful Articles

    283790 INF: How to Create a SQL Server 2000 Trace

    283786 How to monitor SQL Server 2000 traces

    Setting up Perfmon Logs

    One of best ways to monitor your system performance for disk contention, high CPU, memory crunch etc. is to use Windows Performance Monitor Logs and Alerts. These logs can be used to capture historical information about different performance objects and would help us understand what was happening on the system at that point of time. In Windows Server 2008 & Windows Vista, Perfmon has a cool new utilty (a management MMC snap-in) called Reliability Monitor which helps you a bird’s eye view of your system stability.

    Steps to setup Perfmon data collection for Windows Server 2003/XP
    This can be done by opening up Perfmon:

    1. Click on “Performance Logs and Alerts
    2. Click on “Counter Logs
    3. Right click on the same and click on “New Log Settings
    4. Give the log a name
    5. Click on “Add Objects” and add all the objects that are needed for your data collection
    6. Click on the “Log Files” tab
    7. You can change the log file location by clicking on the “Configure” button
    8. Click on the “Schedule” tab and then for “Start Log” and “Stop Log”, select the “Manually (Using the Shortcut menu)” option
    9. Click on the “OK” button to create the log
    10. Then right-click on the Log and click on “Start” to begin the logging
    11. Right-click on the log file and click on “Stop” to end the logging

    How to setup a Perfmon data collection for Windows Server 2008/ Vista/ Windows Server 2008 R2

    1. Open up the Performance Monitor snap-in (Start -> Run -> perfmon)
    2. Expand the “Monitoring Tools” option and Right Click on “Perfomance Monitor” -> “New” -> “Data Collector Set
    3. Give the data collector set a name and click on Next
    4. Give the location where you want to save the Perfmon Logs and click on Next
    5. Here you can provide the Run As user of leave that as the Default user
    6. Select the option “Save and Close” and click on Finish
    7. Then go back to the Perfmon snap-in main window and you should see a Data Collector set with the same name that you created under Data Collector Sets -> User Defined
    8. Click on the Data Collector Set and on the right hand pane, you should see a System Monitor Log Performance Counter. Right click on it and click on properties.
      • Under the Performance Counters tab, add the relevant performance counters required for your data collection, set the log format (binary, SQL, CSV, comma separated) and the sample collection interval time.
      • Under the File tab specify the file format name and logging properties for the file.
    9. Now you can start the Perfmon data collection by right clicking on the Data Collector Set and click on Start or you could do some more work for maintaining disk space by setting up some rules using the Data Manager to create .CAB files or delete older files in case we are setting up perfmon logs for long term monitoring.

    There is hardly any performance impact in collecting perfmon logs on any server. Any perfmon data collection unlike other forms of data collection don’t generate voluminous data in terms of size but contain hordes of infromation which can provide valuable insight to an issue which is impacting critical business applications running on a server.

    Windows Reliability and Performance Monitor

    http://technet.microsoft.com/en-us/library/cc749154.aspx