Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
AIM Några sätt att upptäcka vad som finns i databasen om du är ny på jobbet eller i projektet. Detta inkluderar frågor mot metadata, server och db konfig, perfmon, profiler och blocking. http://www.sqlinform.com/ alter database northwind set single_user with rollback immediate You're new - what stuff do you need to know? The Region Servers Databases Is it safe? ... backups space to grow security The neighbourhood What's Good, What's bad, What is most important Metadata - your local map Primary Keys Clustered Indexes Columns and Datatypes Indexes Stored Procedures Extended Stored Procedures Functions Triggers Table Sizes - width & rows Perfmon SQL Trace What Servers & What Databases (don't assume it's written down) OSQL -L Sp_helpdb Have you got backups(number 1 priority) 2 sets of tables backup tables SELECT 'this database backed up today :', bs.database_name AS DatabaseName, bs.backup_finish_date, MAX(bms.physical_device_name) AS FullBackupName FROM msdb.dbo.backupset bs INNER JOIN msdb.dbo.backupmediafamily bms ON bs.media_set_id = bms.media_set_id INNER JOIN master.dbo.sysdatabases s ON bs.database_name = s.name WHERE CONVERT(VARCHAR(20), bs.backup_finish_date, 112) = CONVERT(VARCHAR(20), GETDATE(), 112) GROUP BY bs.database_name , bs.backup_finish_date sysmaintenance tables see backuptests.txt >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>> REM testbackups.bat REM REM Program to check whether maintenance plan backups have succeeded REM REM Stephen Morris REM REM All servers must be in the serverlist.txt file REM x: CD x:\BackupTesting DEL backupmonitor.txt ECHO "Start" > backupmonitor.txt DATE /T >> backupmonitor.txt FOR /F %%a IN (x:\BackupTesting\serverlist.txt) DO ( ECHO Checking %%a >>backupmonitor.txt osql -S%%a -n -E i"x:\BackupTesting\maintplanbackupchecker2.sql">>backupmonitor.tx t) osql -n -E -i"x:\BackupTesting\smtp_backupmail_call.sql" >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>> REM serverlist.txt HURRICANE LANCASTER TYPHOON LIGHTNING >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>> REM maintplanbackupchecker2.sql declare @HaveBackupsFailed int declare @result_string varchar(8000) set @result_string = '' -- Test that every database in sysdatabases has been backed up and succeeded -- Join the databases in Sysdatabases to the maintenance plan history -- test the succeeded column -- reverse the logic so that failures = 1 SELECT @HaveBackupsFailed = SUM(CASE WHEN IsNull(mp.succeeded, 0) = 1 THEN 0 ELSE 1 END) --select CASE WHEN IsNull(mp.succeeded, 0) = 1 THEN 0 ELSE 1 END as bk , datediff(hh, mp.end_time, getdate()), * FROM master.dbo.sysdatabases db LEFT OUTER JOIN ( Select * FROM msdb.dbo.sysdbmaintplan_history mp WHERE datediff(hh, mp.end_time, getdate()) <= 24 AND mp.activity = 'Backup database' AND mp.database_name not in ('pubs', 'northwind') ) as mp ON db.name = mp.database_name WHERE db.name not in ('pubs', 'northwind', 'tempdb') IF @HaveBackupsFailed > 0 BEGIN SELECT @result_string = @result_string + db.name +', ' FROM master.dbo.sysdatabases db LEFT OUTER JOIN ( Select * FROM msdb.dbo.sysdbmaintplan_history mp WHERE datediff(hh, mp.end_time, getdate()) <= 24 AND mp.activity = 'Backup database' AND mp.database_name not in ('pubs', 'northwind') ) as mp ON db.name = mp.database_name WHERE db.name not in ('pubs', 'northwind', 'tempdb') and isnull(mp.succeeded, 0) = 0 Select @result_string = 'SQL Server Backup Monitor Databases '+@result_string+' - backup failed' RaisError(@result_string, 17, 127) WITH LOG END >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>> REM "Start" Fri 27/05/2005 Checking HURRICANE Checking LANCASTER Checking TYPHOON Msg 50000, Level 17, State 127, Server ROCKET, Line 56 SQL Server Backup Monitor - Databases DYNAMIX, DYNAMIX2, DYNAMIX2005, DYNBAK, EMPLOYEE, Foodmart 2000, HR, INSIGHT, INSIGHTANALYSIS, INSIGHTFUTURE, INSIGHTLOGS, INSIGHTOLD, master, model, msdb, OLAPQueryLog, OLAPRepository, SNOWFLAKE, SUMMIT, TEMP, - backup failed Checking LIGHTNING files sizes and locations sp_msforeachdb 'use ? exec sp_helpfile' security logins & users - roles, permissions sp_helprotect Metadata queries Primary keys print 'no PK' -- no PK select objectpropertyex(id, 'tablehasPrimaryKey') as HasPK , name from sysobjects where type = 'U' and objectpropertyex(id, 'tablehasPrimaryKey')= 0 Clustered indexes print 'no clustered indexes' -- no clustered indexes select objectpropertyex(id, 'tablehasclustindex') , name from sysobjects where objectpropertyex(id, 'tablehasclustindex') = 0 and objectpropertyex(id, 'IsTable') = 1 Clustered PrimaryKeys on UniqueIdentifiers select t.table_name, cc.constraint_name, ObjectProperty(object_id(cc.constraint_name), 'CnstIsClustKey') IsClustered, cc.column_name, co.column_default, co.data_type, co.character_octet_length from information_schema.tables t left outer join information_schema.table_constraints tc on t.table_name = tc.table_name and tc.constraint_type = 'PRIMARY KEY' left outer join information_schema.constraint_column_usage cc on t.table_name = cc.table_name and tc.constraint_name = cc.constraint_name left outer join information_schema.columns co on cc.table_name = co.table_name and cc.column_name = co.column_name where co.data_type = 'uniqueidentifier' order by t.table_name Clustered Indexes on wide Composite Columns -- show PKs and column data types - highlight missing PKs select left(t.table_name,30) as table_name , left(isNull(cc.constraint_name,'!!! No PK !!!'),30) as Constraint_Name, cc.column_name, co.column_default, co.data_type, co.character_octet_length from information_schema.tables t left outer join information_schema.table_constraints tc on t.table_name = tc.table_name and tc.constraint_type = 'PRIMARY KEY' left outer join information_schema.constraint_column_usage cc on t.table_name = cc.table_name and tc.constraint_name = cc.constraint_name left outer join information_schema.columns co on cc.table_name = co.table_name and cc.column_name = co.column_name --where cc.constraint_name is null order by t.table_name Tables Text columns – beware access programmers! select * from information_schema.columns where data_type = 'text' also select top 100 ' select max(datalength('+column_name+')) from '+ table_name from information_schema.columns where data_type = 'text' order by table_name, ordinal_position Number of Rows (via sysindexes) select object_name(id) as tablename, rows from sysindexes where indid = 1 order by 2 desc Non matching column datatypes SELECT table_name, column_name, data_type + CASE WHEN data_type in ('numeric', 'decimal') THEN '('+convert(varchar(10),numeric_precision)+'.'+convert(varchar(10),n umeric_precision_radix)+')' WHEN data_type in ('char', 'nchar', 'varchar', 'nvarchar') THEN '('+convert(varchar(10), character_maximum_length) + ')' ELSE '' END AS DataType FROM information_schema.columns WHERE column_name in ( SELECT column_name FROM ( SELECT column_name, data_type + CASE WHEN data_type in ('numeric', 'decimal') THEN '('+convert(varchar(10),numeric_precision)+'.'+convert(varchar(10),n umeric_precision_radix)+')' WHEN data_type in ('char', 'nchar', 'varchar', 'nvarchar') THEN '('+convert(varchar(10), character_maximum_length) + ')' ELSE '' END AS DataType, count(*) AS colcount FROM information_schema.columns GROUP BY column_name, data_type + CASE WHEN data_type in ('numeric', 'decimal') THEN '('+convert(varchar(10),numeric_precision)+'.'+convert(varchar(10),n umeric_precision_radix)+')' WHEN data_type in ('char', 'nchar', 'varchar', 'nvarchar') THEN '('+convert(varchar(10), character_maximum_length) + ')' ELSE '' END ) AS x GROUP BY column_name HAVING count(*) > 1 ) ORDER BY column_name , table_name DBCC ShowContig --USE ScaleDB SET NOCOUNT ON DECLARE @tablename VARCHAR (128) DECLARE @execstr VARCHAR (255) DECLARE @objectid INT DECLARE @indexid INT DECLARE @frag DECIMAL DECLARE @maxfrag DECIMAL -- Decide on the maximum fragmentation to allow SELECT @maxfrag = 30.0 -- Declare cursor DECLARE tables CURSOR FOR SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' -- Create the table IF Object_ID('tempdb..#fraglist') IS NOT NULL DROP TABLE #fraglist CREATE TABLE #fraglist ( ObjectName CHAR (255), ObjectId INT, IndexName CHAR (255), IndexId INT, Lvl INT, CountPages INT, CountRows INT, MinRecSize INT, MaxRecSize INT, AvgRecSize INT, ForRecCount INT, Extents INT, ExtentSwitches INT, AvgFreeBytes INT, AvgPageDensity INT, ScanDensity DECIMAL, BestCount INT, ActualCount INT, LogicalFrag DECIMAL, ExtentFrag DECIMAL) -- Open the cursor OPEN tables -- Loop through all the tables in the database FETCH NEXT FROM tables INTO @tablename WHILE @@FETCH_STATUS = 0 BEGIN -- Do the showcontig of all indexes of the table INSERT INTO #fraglist EXEC ('DBCC SHOWCONTIG (''' + @tablename + ''') WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS') FETCH NEXT FROM tables INTO @tablename END -- Close and deallocate the cursor CLOSE tables DEALLOCATE tables Select * from #fraglist where countpages > 100 order by convert(decimal(9,3), bestcount)/convert(decimal(9,3), actualcount) asc Triggers SELECT object_name(parent_obj), object_name(id), objectpropertyex(id, 'IsTrigger') FROM sysobjects WHERE objectpropertyex(id, 'IsTrigger') = 1 Views SELECT c.* FROM information_schema.tables t JOIN information_schema.columns c ON t.table_name = c.table_name WHERE t.table_type = 'VIEW' Functions select * from information_schema.routines where routine_type = 'FUNCTION' Indexes -- to get indexes by table - a bit clunky but works OK if object_id('tempdb..#t1') is not null drop table #t1 CREATE table #t1 ( do integer default(0), index_name varchar(100), index_descrip varchar(200), index_keys varchar(200), table_name varchar(100) ) exec sp_msforeachtable "insert #t1 (index_name, index_descrip, index_keys) exec sp_helpindex '?'; update #t1 set table_name = '?', do = 1 where do = 0" update #t1 set table_name = replace(table_name , '[', '') update #t1 set table_name = replace(table_name , ']', '') update #t1 set table_name = replace(table_name , 'dbo.', '') -- Fog & Spot tables relate to Quest s/w delete #t1 where table_name like 'Fog%' delete #t1 where table_name like 'Spot%' select left(table_name, 30) as table_name ,left(index_name,40) as index_name ,left(index_keys, 40) as index_keys ,left(index_descrip,50) as index_descrip from #t1 order by table_name, index_keys Default Constraints -- try PUBS select * from INFORMATION_SCHEMA.COLUMNS where column_default is not null User Defined Datatypes (show hands) select * from INFORMATION_SCHEMA.DOMAIN_CONSTRAINTS Unique Constraints -- try adventureworks select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where constraint_type = 'unique' Extended Stored Procedures Select * from sysobjects where objectpropertyex(id, 'IsExtendedProc') =1 Stored Procedures Startup Stored Procedures Select * from sysobjects where objectpropertyex(id, 'ExecIsStartup') = 1 Searching Stored Procedures Simplistic -- try northwind select object_name(id) as ProcName, text from syscomments where text like '%orders%' and objectproperty(id, 'IsProcedure') = 1 Or try searching for select object_name(id), text from syscomments where text like '%exec%' or text like ‘%sp_executesql%’ Or select object_name(id), text from syscomments where text like '%xp_cmdshell%' etc Server configuration & Database configuration /* -- TSQL CODE TO LIST OUT SERVER SETTINGS set nocount on select @@servername exec sp_configure -------------------------- TSQL CODE TO LIST OUT DATABASE SETTINGS set nocount on set ansi_warnings off drop table #p create table #p(db varchar(100), propertyvalue sql_variant, propertyname varchar(50)) insert #p select db_name() as db, databasepropertyex(db_name(),'Collation'), 'Collation' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsAnsiNullDefault'), 'IsAnsiNullDefault' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsAnsiNullsEnabled'), 'IsAnsiNullsEnabled' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsAnsiPaddingEnabled'), 'IsAnsiPaddingEnabled' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsAnsiWarningsEnabled'), 'IsAnsiWarningsEnabled' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsArithmeticAbortEnabled'), 'IsArithmeticAbortEnabled' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsAutoClose'), 'IsAutoClose' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsAutoCreateStatistics'), 'IsAutoCreateStatistics' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsAutoShrink'), 'IsAutoShrink' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsAutoUpdateStatistics'), 'IsAutoUpdateStatistics' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsCloseCursorsOnCommitEnabled '), 'IsCloseCursorsOnCommitEnabled' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsFulltextEnabled'), 'IsFulltextEnabled' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsInStandBy'), 'IsInStandBy' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsLocalCursorsDefault'), 'IsLocalCursorsDefault' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsMergePublished'), 'IsMergePublished' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsNullConcat'), 'IsNullConcat' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsNumericRoundAbortEnabled'), 'IsNumericRoundAbortEnabled' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsQuotedIdentifiersEnabled'), 'IsQuotedIdentifiersEnabled' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsRecursiveTriggersEnabled'), 'IsRecursiveTriggersEnabled' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsSubscribed'), 'IsSubscribed' as property insert #p select db_name() as db, databasepropertyex(db_name(),'IsTornPageDetectionEnabled'), 'IsTornPageDetectionEnabled' as property insert #p select db_name() as db, databasepropertyex(db_name(),'Recovery'), 'Recovery' as property insert #p select db_name() as db, databasepropertyex(db_name(),'SQLSortOrder'), 'SQLSortOrder' as property insert #p select db_name() as db, databasepropertyex(db_name(),'Status'), 'Status' as property insert #p select db_name() as db, databasepropertyex(db_name(),'Updateability'), 'Updateability' as property insert #p select db_name() as db, databasepropertyex(db_name(),'UserAccess'), 'UserAccess' as property insert #p select db_name() as db, databasepropertyex(db_name(),'Version'), 'Version' as property select @@servername select left(db, 20) as db , propertyname, convert(varchar(30), propertyvalue) as pvalue from #p */ Profiler A very important tool Try tracing for Scans & include Reads Stored Procedure execution counts and durations For debugging To create replay scripts - for testing As an input to the Index Tuning Wizard ? To audit DDL events A quick look at Stored Procedure execution counts and durations USE Operations SET ANSI_PADDING OFF GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[ProfilerJobInfo]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[ProfilerJobInfo] GO if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[ProfilerJobInfo]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) BEGIN CREATE TABLE [dbo].[ProfilerJobInfo] ( [ProfilerJobInfoID] [int] IDENTITY (1, 1) NOT NULL , [filestring] [nvarchar] (200) COLLATE Finnish_Swedish_CI_AS NULL , [maxfilesize] [int] NULL , [runminutes] [int] NULL , [runstarttime] [datetime] NULL ) END GO Use MSDB -- Script generated on 10/6/2005 11:37 AM -- By: b2bpoker\administrator -- Server: 192.168.7.253 BEGIN TRANSACTION DECLARE @JobID BINARY(16) DECLARE @ReturnCode INT SELECT @ReturnCode = 0 IF (SELECT COUNT(*) FROM msdb.dbo.syscategories WHERE name = N'[Uncategorized (Local)]') < 1 EXECUTE msdb.dbo.sp_add_category @name = N'[Uncategorized (Local)]' -- Delete the job with the same name (if it exists) SELECT @JobID = job_id FROM msdb.dbo.sysjobs WHERE (name = N'SQL Trace Analysis') IF (@JobID IS NOT NULL) BEGIN -- Check if the job is a multi-server job IF (EXISTS (SELECT * FROM msdb.dbo.sysjobservers WHERE (job_id = @JobID) AND (server_id <> 0))) BEGIN -- There is, so abort the script RAISERROR (N'Unable to import job ''SQL Trace Analysis'' since there is already a multi-server job with this name.', 16, 1) GOTO QuitWithRollback END ELSE -- Delete the [local] job EXECUTE msdb.dbo.sp_delete_job @job_name = N'SQL Trace Analysis' SELECT @JobID = NULL END BEGIN -- Add the job EXECUTE @ReturnCode = msdb.dbo.sp_add_job @job_id = @JobID OUTPUT , @job_name = N'SQL Trace Analysis', @owner_login_name = N'sa', @description = N'No description available.', @category_name = N'[Uncategorized (Local)]', @enabled = 1, @notify_level_email = 0, @notify_level_page = 0, @notify_level_netsend = 0, @notify_level_eventlog = 2, @delete_level= 0 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback -- Add the job steps EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @JobID, @step_id = 1, @step_name = N'Setup Trace File - wait for completion', @command = N'declare @rc int declare @TraceID int declare @maxfilesize bigint declare @datestr nvarchar(30) declare @pathstr nvarchar(100) declare @filestr nvarchar(130) declare @now datetime declare @stopat datetime declare @runminutes integer declare @waitstr varchar(20) declare @waithh varchar(10) declare @waitmi varchar(10) -- EDIT here to set the location to save the file to -- or to change the maximum size of the file set @pathstr = N''c:\sql_traces\'' set @maxfilesize = 100 set @runminutes = 7 select @now = getdate() select @stopat = dateadd(mi, @runminutes, @now) select @datestr = convert(varchar(30), @now , 100) select @datestr = replace(@datestr, '' '','' '') select @datestr = replace(@datestr, '' '',''_'') select @waithh = right( ''000'' + convert(varchar(5), @runminutes / 60), 3) select @waitmi = right( ''00'' + convert(varchar(5), @runminutes % 60), 2) select @waitstr = @waithh +'':''+@waitmi+'':000'' select @filestr = @pathstr + @datestr -- so we can get the filename for the analysis step Insert operations.dbo.ProfilerJobInfo ( filestring, maxfilesize, runminutes, runstarttime ) VALUES ( @filestr+''.trc'', @maxfilesize, @runminutes, getdate() ) exec @rc = sp_trace_create @TraceID output, 2, @filestr, @maxfilesize, @stopat if (@rc != 0) goto error -- Set the events declare @on bit set @on = 1 exec sp_trace_setevent exec sp_trace_setevent exec sp_trace_setevent exec sp_trace_setevent exec sp_trace_setevent exec sp_trace_setevent @TraceID, @TraceID, @TraceID, @TraceID, @TraceID, @TraceID, 17, 17, 17, 17, 17, 17, 1, @on 3, @on 12, @on 13, @on 14, @on 22, @on exec exec exec exec exec exec @TraceID, @TraceID, @TraceID, @TraceID, @TraceID, @TraceID, 43, 43, 43, 43, 43, 43, 1, @on 3, @on 12, @on 13, @on 14, @on 22, @on sp_trace_setevent sp_trace_setevent sp_trace_setevent sp_trace_setevent sp_trace_setevent sp_trace_setevent -- Set the Filters declare @intfilter int declare @bigintfilter bigint exec sp_trace_setfilter @TraceID, 10, 0, 7, N''SQL Profiler'' -- start trace exec sp_trace_setstatus @TraceID, 1 -- display trace id for future references select TraceID=@TraceID WAITFOR DELAY @waitstr -- wait until finished goto theend error: RaisError(@rc, 16,1) theend: ', @database_name = N'master', @server = N'', @database_user_name = N'', @subsystem = N'TSQL', @cmdexec_success_code = 0, @flags = 0, @retry_attempts = 0, @retry_interval = 1, @output_file_name = N'', @on_success_step_id = 0, @on_success_action = 3, @on_fail_step_id = 0, @on_fail_action =2 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @JobID, @step_id = 2, @step_name = N'Analyse the file', @command = N'SET NOCOUNT ON declare @filestr nvarchar(130) ,@startdate datetime ,@traceduration int Select TOP 1 @filestr = filestring , @startdate = runstarttime, @traceduration = runminutes FROM operations.dbo.ProfilerJobInfo Order By ProfilerJobInfoID Desc IF Object_ID(''tempdb..#obj'') Is Not NULL BEGIN DROP TABLE #obj END CREATE TABLE #obj ( objid integer, objname varchar(150), CONSTRAINT [PK_Obj_ObjID] PRIMARY KEY CLUSTERED ( [ObjId] ) ) IF Object_ID(''tempdb..#sql_trace'') Is Not NULL BEGIN DROP TABLE #sql_trace END CREATE TABLE #sql_trace ( [RowNumber] [int] IDENTITY (1, 1) NOT NULL , [EventClass] [int] NULL , -[sqltxt] [varchar] (2000) NULL , [SPID] [int] NULL , [Duration] [bigint] NULL , [StartTime] [datetime] NULL , [ObjectID] [int] NULL, CONSTRAINT [PK_SQL_Trace] PRIMARY KEY CLUSTERED ( ) [RowNumber] ) INSERT #obj ( objid, objname ) SELECT [ID], [Name] -- Check the database name FROM northwind.dbo.sysobjects WHERE Type = ''P'' INSERT #sql_trace ( EventClass, -sqltxt, SPID, Duration, StartTime, ObjectID ) SELECT EventClass, -convert(varchar(2000), textdata), SPID, Duration, StartTime, ObjectID FROM ::fn_trace_gettable(@filestr, default) Create Index IX_SQLTrace_ObjID ON #sql_trace(ObjectID) SELECT rtrim(@filestr) as filestring , @startdate as runstarttime, @traceduration as runminutes select ''stored procs ordered by total duration'' select left(o.objname, 35) as procs, sum(duration) totduration_ms, convert(money, convert(decimal(15,2),sum(duration))/convert(decimal(15,2),count(du ration))) as avgduration, count(duration) as count_execs from #sql_trace s join #obj o on s.objectid = o.objid group by o.objname order by 2 desc select ''stored procs ordered by average duration'' select left(o.objname, 35) as procs, sum(duration) totduration_ms, convert(money, convert(decimal(15,2),sum(duration))/convert(decimal(15,2),count(du ration))) as avgduration, count(duration) as count_execs from #sql_trace s join #obj o on s.objectid = o.objid group by o.objname order by 3 desc select ''stored procs ordered by count of executions'' select left(o.objname, 35) as procs, sum(duration) totduration_ms, convert(money, convert(decimal(15,2),sum(duration))/convert(decimal(15,2),count(du ration))) as avgduration, count(duration) as count_execs from #sql_trace s join #obj o on s.objectid = o.objid group by o.objname order by 4 desc ', @database_name = N'master', @server = N'', @database_user_name = N'', @subsystem = N'TSQL', @cmdexec_success_code = 0, @flags = 2, @retry_attempts = 0, @retry_interval = 1, @output_file_name = N'C:\perflogs\trace_analysis.out', @on_success_step_id = 0, @on_success_action = 1, @on_fail_step_id = 0, @on_fail_action = 2 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXECUTE @ReturnCode = msdb.dbo.sp_update_job @job_id = @JobID, @start_step_id = 1 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback -- Add the Target Servers EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @JobID, @server_name = N'(local)' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback END COMMIT TRANSACTION GOTO EndSave QuitWithRollback: IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION EndSave: Blocking Why reinvent the wheel Sherlock.exe www.sqlteam.com & sp_blocker_pss80 http://support.microsoft.com/default.aspx?scid=kb;en-us;271509 Deadlocks Use DBCC TRACEON (1204, 3605, -1) Writes the information to the error log General hints Short transactions Server side not client side Access objects consistently in the same order Use an updlock hint