Database Journal
MS SQL Oracle DB2 Access MySQL PostgreSQL Sybase PHP SQL Etc SQL Scripts & Samples Links Database Forum

» Database Journal Home
» Database Articles
» Database Tutorials
MS SQL
Oracle
DB2
MS Access
MySQL
» RESOURCES
Database Tools
SQL Scripts & Samples
Links
» Database Forum
» Sitemap
Free Newsletters:
DatabaseDaily  
News Via RSS Feed


follow us on Twitter
Database Journal |DBA Support |SQLCourse |SQLCourse2
 

Featured Database Articles

MS SQL

Posted Jul 30, 2003

Scripting Traces for Performance Monitoring on SQL Server - Page 3

By Andrew Novick

Loading the Trace Script into a Table

Working with trace data in disk file is not easy. I suppose it is possible to load the data into Excel, SAS, or some other analysis tool. However, I find that the best place to work with the data is in a SQL table. The next step in the process loads the trace file on disk into a table for analysis.

If you ask SQL Profiler to create the trace into a table for you, it creates a table with just the columns that you have selected for the trace. Since SQL Profiler knows which columns it's recording, letting it create a table is sufficient for one time use. However, for reporting purposes, having different traces in different tables is inconvenient. The best approach is to use a table that can store all columns of any trace. Having a single table also helps because there might be additional columns recorded as the trace is modified over time. The next listing has the CREATE TABLE script for dbaTraceDetail that does just that.

CREATE TABLE dbo.dbaTraceDetail (
        dbaTraceID int NOT NULL ,
        RowNumber int IDENTITY (1, 1) NOT NULL ,
        StartTime datetime NULL ,
        EndTime datetime NULL ,
        EventClass int NULL ,
        EventSubClass int NULL ,
        TextData ntext NULL ,
        BinaryData image NULL ,
        Duration bigint NULL ,
        Reads bigint NULL ,
        Writes bigint NULL ,
        CPU int NULL ,
        DatabaseID int NULL ,
        DatabaseName nvarchar (128) NULL ,
        TransactionID bigint NULL ,
        SPID int NULL ,
        NTUserName nvarchar (128) NULL ,
        NTDomainName nvarchar (128) NULL ,
        HostName nvarchar (128) NULL ,
        ClientProcessID int NULL ,
        LoginName nvarchar (128) NULL ,
        DBUserName nvarchar (128) NULL ,
        ApplicationName nvarchar (128) NULL ,
        [Permissions] int NULL ,
        Severity int NULL ,
        Success int NULL ,
        IndexID int NULL ,
        IntegerData int NULL ,
        ServerName nvarchar (128) NULL ,
        ObjectType int NULL ,
        NestLevel int NULL ,
        State int NULL ,
        Error int NULL ,
        Mode int NULL ,
        Handle int NULL ,
        ObjectID int NULL ,
        ObjectName nvarchar (128) NULL ,
        FileName nvarchar (128) NULL ,
        OwnerName nvarchar (128) NULL ,
        RoleName nvarchar (128) NULL ,
        TargetUserName nvarchar (128) NULL ,
        LoginSid image NULL ,
        TargetLoginName nvarchar (128) NULL ,
        TargetLoginSid image NULL ,
        ColumnPermissions int NULL 
        , CONSTRAINT dbaTraceDetail_PK PRIMARY KEY CLUSTERED
            (dbaTraceID, RowNumber ) on [PRIMARY]
, CONSTRAINT dbaTraceDetail_FK_dbaTrace FOREIGN KEY (dbaTraceID) REFERENCES dbo.dbaTrace (dbaTraceID)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO

As you can see down in the shaded area near the bottom of the script, the table has a foreign key relationship with the dbaTrace table created in the previous section. By having the dbaTraceID column as the lead part of the key, many traces can be kept in the same table. Since the table has every column that could be included in a trace, any trace can be loaded into it.

Loading the table from the trace file relies on one of SQL Server's system user-defined functions. "System" and "user-defined" might sound like a contradiction, but they are functions, written in T-SQL using the CREATE FUNCTION statement, that SQL Server adds to itself during installation. The function in question is fn_trace_gettable. It is incorporated into the stored procedure dba_Trc_LoadFile that follows. The call to fn_get_sql is in the shaded line.

CREATE PROCEDURE dbo.dba_Trc_LoadFile 

    @FileName        nvarchar(256) -- File to load
  , @dbaTraceID         int  -- Id of dbaTrace use
  , @DeleteOldRows   BIT = 1 -- Should Old Rows be removed?
  , @RowsLoaded      int  OUTPUT -- Rows of trace data loaded
AS 
/*
* Loads a trace file from disk into the dbaTraceDetail table and
* updates the corresponding dbaTrace row to reflect that the file
* has bee loaded.
*
DECLARE @Rows int, @RC int
exec @RC = dbo.dba_Trc_LoadFile 'c:\ExampleTrace.trc'
                 , 1 , default, @Rows OUTPUT
PRINT 'Loaded ' + CONVERT(varchar(9), @Rows) + ' Rows   RC = ' 
                 + CONVERT (varchar(9), @RC)
****************************************************************/

DECLARE @myError         int        -- Local copy of @@Error
      , @myRowcount      int     -- Local copy of @@ROWCOUNT

SET NOCOUNT ON -- Don't report the count of effected rows

BEGIN TRANSACTION

-- Remove any old rows from the trace.
IF @DeleteOldRows = 1 BEGIN 
    DELETE FROM dbo.dbaTraceDetail WHERE dbaTraceID=@dbaTraceID
    SELECT @myError = @@Error, @myRowcount = @@Rowcount
    IF @myError <> 0 BEGIN
       ROLLBACK TRANSACTION   
       RETURN @myError
    END    
END

-- This statement loads the file
INSERT INTO dbo.dbaTraceDetail 
       (dbaTraceID, StartTime, EndTime, EventClass, EventSubClass
      , TextData, BinaryData, Duration, Reads, Writes, CPU, DatabaseID
      , DatabaseName, TransactionID, SPID, NTUserName, NTDomainName
      , HostName, ClientProcessID, LoginName, DBUserName
      , ApplicationName, [Permissions], Severity, Success, IndexID
      , IntegerData, ServerName, ObjectType, NestLevel, State, Error
      , Mode, Handle, ObjectID, ObjectName, [FileName], OwnerName
      , RoleName, TargetUserName, LoginSid
      , TargetLoginName, TargetLoginSid, ColumnPermissions)
   SELECT @dbaTraceID, StartTime, EndTime, EventClass, EventSubClass
      , TextData, BinaryData, Duration, Reads, Writes, CPU, DatabaseID
      , DatabaseName, TransactionID, SPID, NTUserName, NTDomainName
      , HostName, ClientProcessID, LoginName, DBUserName
      , ApplicationName, [Permissions], Severity, Success, IndexID
      , IntegerData, ServerName, ObjectType, NestLevel, State, Error
      , Mode, Handle, ObjectID, ObjectName, [FileName], OwnerName
      , RoleName, TargetUserName, LoginSid
      , TargetLoginName, TargetLoginSid, ColumnPermissions
FROM ::fn_trace_gettable(@FileName, default)
SELECT @myError = @@Error, @myRowcount = @@Rowcount IF @myError <> 0 BEGIN ROLLBACK TRANSACTION RETURN @myError END SET @RowsLoaded = @myRowcount -- Save the count for output -- Update the time when the file was loaded. UPDATE dbo.dbaTrace SET FileLoadedDT = getdate() WHERE @dbaTraceID = dbaTraceID SELECT @myError = @@Error, @myRowcount = @@Rowcount IF @myError <> 0 BEGIN ROLLBACK TRANSACTION RETURN @myError END COMMIT TRANSACTION SELECT @myError = @@Error RETURN @myError -- Should be zero, unless there was an error on COMMIT

Unless I am really interested in seeing what's in the trace, I run this in a separate job that loads all the available files. It is scheduled to run in the early morning hours when system activity is low.

Conclusion

By using SQL Profiler's ability to create the T-SQL script for a trace, this article has shown how easy it is to create a stored procedure that can be run every day during times of peak activity. That is the best time to find out where SQL Server is using the most resources so any performance problems can be addressed. By shifting the effort of loading the data to an off peak time, the overhead of monitoring performance is moved out of peak hours.

Of course, what you have seen here is the process of gathering the performance data. Once you have it, there are various ways to analyze it. I usually run a variety of reports that show the longest running statements, the table scans, or any deadlocks that have occurred.

» See All Articles by Columnist Andrew Novick



MS SQL Archives

Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 




Latest Forum Threads
MS SQL Forum
Topic By Replies Updated
SQL 2005: SSIS: Error using SQL Server credentials poverty 3 August 17th, 07:43 AM
Need help changing table contents nkawtg 1 August 17th, 03:02 AM
SQL Server Memory confifuration bhosalenarayan 2 August 14th, 05:33 AM
SQL Server Primary Key and a Unique Key katty.jonh 2 July 25th, 10:36 AM