@@ -24,6 +24,7 @@ ALTER PROCEDURE dbo.sp_BlitzIndex
2424 @SkipStatistics BIT = 1 ,
2525 @GetAllDatabases BIT = 0 ,
2626 @BringThePain BIT = 0 ,
27+ @IgnoreDatabases NVARCHAR (MAX ) = NULL , /* Comma-delimited list of databases you want to skip */
2728 @ThresholdMB INT = 250 /* Number of megabytes that an object must be before we include it in basic results */ ,
2829 @OutputType VARCHAR (20 ) = ' TABLE' ,
2930 @OutputServerName NVARCHAR (256 ) = NULL ,
@@ -119,12 +120,14 @@ DECLARE @collation NVARCHAR(256);
119120DECLARE @NumDatabases INT ;
120121DECLARE @LineFeed NVARCHAR (5 );
121122DECLARE @DaysUptimeInsertValue NVARCHAR (256 );
123+ DECLARE @DatabaseToIgnore NVARCHAR (MAX );
122124
123125SET @LineFeed = CHAR (13 ) + CHAR (10 );
124126SELECT @SQLServerProductVersion = CAST (SERVERPROPERTY (' ProductVersion' ) AS NVARCHAR (128 ));
125127SELECT @SQLServerEdition = CAST (SERVERPROPERTY (' EngineEdition' ) AS INT ); /* We default to online index creates where EngineEdition=3*/
126128SET @FilterMB= 250 ;
127129SELECT @ScriptVersionName = ' sp_BlitzIndex(TM) v' + @Version + ' - ' + DATENAME (MM, @VersionDate) + ' ' + RIGHT (' 0'+ DATENAME (DD, @VersionDate),2 ) + ' , ' + DATENAME (YY, @VersionDate);
130+ SET @IgnoreDatabases = LTRIM (RTRIM (@IgnoreDatabases));
128131
129132RAISERROR (N ' Starting run. %s' , 0 ,1 , @ScriptVersionName) WITH NOWAIT ;
130133
@@ -203,6 +206,9 @@ IF OBJECT_ID('tempdb..#CheckConstraints') IS NOT NULL
203206IF OBJECT_ID (' tempdb..#FilteredIndexes' ) IS NOT NULL
204207 DROP TABLE #FilteredIndexes;
205208
209+ IF OBJECT_ID (' tempdb..#Ignore_Databases' ) IS NOT NULL
210+ DROP TABLE #Ignore_Databases
211+
206212 RAISERROR (N ' Create temp tables.' ,0 ,1 ) WITH NOWAIT ;
207213 CREATE TABLE #BlitzIndexResults
208214 (
@@ -685,6 +691,12 @@ IF OBJECT_ID('tempdb..#FilteredIndexes') IS NOT NULL
685691 column_name NVARCHAR (128 ) NULL
686692 );
687693
694+ CREATE TABLE #Ignore_Databases
695+ (
696+ DatabaseName NVARCHAR (128 ),
697+ Reason NVARCHAR (100 )
698+ );
699+
688700/* Sanitize our inputs */
689701SELECT
690702 @OutputServerName = QUOTENAME (@OutputServerName),
@@ -733,6 +745,37 @@ IF @GetAllDatabases = 1
733745 END ;
734746 END ;
735747
748+ IF @IgnoreDatabases IS NOT NULL
749+ AND LEN (@IgnoreDatabases) > 0
750+ BEGIN
751+ RAISERROR (N ' Setting up filter to ignore databases' , 0 , 1 ) WITH NOWAIT ;
752+ SET @DatabaseToIgnore = ' ' ;
753+
754+ WHILE LEN (@IgnoreDatabases) > 0
755+ BEGIN
756+ IF PATINDEX (' %,%' , @IgnoreDatabases) > 0
757+ BEGIN
758+ SET @DatabaseToIgnore = SUBSTRING (@IgnoreDatabases, 0 , PATINDEX (' %,%' ,@IgnoreDatabases)) ;
759+
760+ INSERT INTO #Ignore_Databases (DatabaseName, Reason)
761+ SELECT @DatabaseToIgnore, ' Specified in the @IgnoreDatabases parameter'
762+ OPTION (RECOMPILE ) ;
763+
764+ SET @IgnoreDatabases = SUBSTRING (@IgnoreDatabases, LEN (@DatabaseToIgnore + ' ,' ) + 1 , LEN (@IgnoreDatabases)) ;
765+ END ;
766+ ELSE
767+ BEGIN
768+ SET @DatabaseToIgnore = @IgnoreDatabases ;
769+ SET @IgnoreDatabases = NULL ;
770+
771+ INSERT INTO #Ignore_Databases (DatabaseName, Reason)
772+ SELECT @DatabaseToIgnore, ' Specified in the @IgnoreDatabases parameter'
773+ OPTION (RECOMPILE ) ;
774+ END ;
775+ END ;
776+
777+ END
778+
736779 END ;
737780ELSE
738781 BEGIN
@@ -818,16 +861,72 @@ BEGIN CATCH
818861 RETURN ;
819862 END CATCH ;
820863
864+
865+ RAISERROR (N ' Checking partition counts to exclude databases with over 100 partitions' ,0 ,1 ) WITH NOWAIT ;
866+ IF @BringThePain = 0 AND @SkipPartitions = 0 AND @TableName IS NULL
867+ BEGIN
868+ DECLARE partition_cursor CURSOR FOR
869+ SELECT dl .DatabaseName
870+ FROM #DatabaseList dl
871+ LEFT OUTER JOIN #Ignore_Databases i ON dl .DatabaseName = i .DatabaseName
872+ WHERE COALESCE (dl .secondary_role_allow_connections_desc , ' OK' ) <> ' NO'
873+ AND i .DatabaseName IS NULL
874+
875+ OPEN partition_cursor
876+ FETCH NEXT FROM partition_cursor INTO @DatabaseName
877+
878+ WHILE @@FETCH_STATUS = 0
879+ BEGIN
880+ /* Count the total number of partitions */
881+ SET @dsql = N' SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
882+ SELECT @RowcountOUT = SUM(1) FROM ' + QUOTENAME (@DatabaseName) + ' .sys.partitions WHERE partition_number > 1 OPTION ( RECOMPILE );' ;
883+ EXEC sp_executesql @dsql, N ' @RowcountOUT BIGINT OUTPUT' , @RowcountOUT = @Rowcount OUTPUT ;
884+ IF @Rowcount > 100
885+ BEGIN
886+ RAISERROR (N ' Skipping database %s because > 100 partitions were found. To check this database, you must set @BringThePain = 1.' ,0 ,1 ,@DatabaseName) WITH NOWAIT ;
887+ INSERT INTO #Ignore_Databases (DatabaseName, Reason)
888+ SELECT @DatabaseName, ' Over 100 partitions found - use @BringThePain = 1 to analyze'
889+ END ;
890+ FETCH NEXT FROM partition_cursor INTO @DatabaseName
891+ END ;
892+ CLOSE partition_cursor
893+ DEALLOCATE partition_cursor
894+
895+ END ;
896+
897+ INSERT #BlitzIndexResults ( Priority, check_id, findings_group, finding, URL , details, index_definition,
898+ index_usage_summary, index_size_summary )
899+ SELECT 1 , 0 ,
900+ ' Database Skipped' ,
901+ i .DatabaseName ,
902+ ' http://FirstResponderKit.org' ,
903+ i .Reason , ' ' , ' ' , ' '
904+ FROM #Ignore_Databases i;
905+
906+
907+ /* Last startup */
908+ SELECT @DaysUptime = CAST (DATEDIFF (HOUR, create_date, GETDATE ()) / 24 . AS NUMERIC (23 ,2 ))
909+ FROM sys .databases
910+ WHERE database_id = 2 ;
911+
912+ IF @DaysUptime = 0 OR @DaysUptime IS NULL
913+ SET @DaysUptime = .01 ;
914+
915+ SELECT @DaysUptimeInsertValue = ' Server: ' + (CONVERT (VARCHAR (256 ), (SERVERPROPERTY (' ServerName' )))) + ' Days Uptime: ' + RTRIM (@DaysUptime);
916+
917+
821918/* Permission granted or unnecessary? Ok, let's go! */
822919
920+ RAISERROR (N ' Starting loop through databases' ,0 ,1 ) WITH NOWAIT ;
823921DECLARE c1 CURSOR
824922LOCAL FAST_FORWARD
825923FOR
826- SELECT DatabaseName
827- FROM #DatabaseList
828- WHERE COALESCE (secondary_role_allow_connections_desc, ' OK' )
829- <> ' NO'
830- ORDER BY DatabaseName;
924+ SELECT dl .DatabaseName
925+ FROM #DatabaseList dl
926+ LEFT OUTER JOIN #Ignore_Databases i ON dl .DatabaseName = i .DatabaseName
927+ WHERE COALESCE (dl .secondary_role_allow_connections_desc , ' OK' ) <> ' NO'
928+ AND i .DatabaseName IS NULL
929+ ORDER BY dl .DatabaseName ;
831930
832931OPEN c1;
833932FETCH NEXT FROM c1 INTO @DatabaseName;
@@ -845,24 +944,14 @@ FROM sys.databases
845944 AND user_access_desc= ' MULTI_USER'
846945 AND state_desc = ' ONLINE' ;
847946
848- /* Last startup */
849- SELECT @DaysUptime = CAST (DATEDIFF (HOUR, create_date, GETDATE ()) / 24 . AS NUMERIC (23 ,2 ))
850- FROM sys .databases
851- WHERE database_id = 2 ;
852-
853- IF @DaysUptime = 0 OR @DaysUptime IS NULL
854- SET @DaysUptime = .01 ;
855-
856- SELECT @DaysUptimeInsertValue = ' Server: ' + (CONVERT (VARCHAR (256 ), (SERVERPROPERTY (' ServerName' )))) + ' Days Uptime: ' + RTRIM (@DaysUptime);
857-
858947-- --------------------------------------
859948-- STEP 1: OBSERVE THE PATIENT
860949-- This step puts index information into temp tables.
861950-- --------------------------------------
862951BEGIN TRY
863952 BEGIN
864953
865- -- Validate SQL Server Verson
954+ -- Validate SQL Server Version
866955
867956 IF (SELECT LEFT (@SQLServerProductVersion,
868957 CHARINDEX (' .' ,@SQLServerProductVersion,0 )- 1
0 commit comments