@@ -71,10 +71,6 @@ BEGIN TRY
7171 @version = ' 1.4' ,
7272 @version_date = ' 20250401' ;
7373
74- SELECT
75- for_insurance_purposes =
76- N ' ALWAYS TEST THESE RECOMMENDATIONS IN A NON-PRODUCTION ENVIRONMENT FIRST!' ;
77-
7874 /*
7975 Help section, for help.
8076 Will become more helpful when out of beta.
@@ -88,13 +84,13 @@ BEGIN TRY
8884 help = N ' this is a script to help clean up unused and duplicate indexes.'
8985 UNION ALL
9086 SELECT
91- help = N ' it will also give you scripted out statements to add page compression to uncompressed indexes.'
87+ help = N ' it will also help you add page compression to uncompressed indexes.'
9288 UNION ALL
9389 SELECT
9490 help = N ' always validate all changes against a non-production environment!'
9591 UNION ALL
9692 SELECT
97- help = N ' without careful analysis and consideration, index changes can negative impacts on performance .' ;
93+ help = N ' please test carefully .' ;
9894
9995 /*
10096 Parameters
@@ -209,7 +205,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
209205 DECLARE
210206 /* general script variables*/
211207 @sql nvarchar (max ) = N ' ' ,
212- @database_id integer = NULL ,
213208 @object_id integer = NULL ,
214209 @full_object_name nvarchar (768 ) = NULL ,
215210 @uptime_warning bit = 0 , /* Will set after @uptime_days is calculated */
@@ -702,6 +697,55 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
702697 END ;
703698 END ;
704699
700+ IF @get_all_databases = 1
701+ AND @include_databases IS NOT NULL
702+ BEGIN
703+ INSERT
704+ #requested_but_skipped_databases
705+ WITH
706+ (TABLOCK )
707+ (
708+ database_name ,
709+ reason
710+ )
711+ SELECT
712+ id .database_name ,
713+ reason =
714+ CASE
715+ WHEN d .name IS NULL
716+ THEN ' Database does not exist'
717+ WHEN d .state <> 0
718+ THEN ' Database not online'
719+ WHEN d .is_in_standby = 1
720+ THEN ' Database is in standby'
721+ WHEN d .is_read_only = 1
722+ THEN ' Database is read-only'
723+ WHEN d .database_id <= 4
724+ THEN ' System database'
725+ ELSE ' Other issue'
726+ END
727+ FROM #include_databases AS id
728+ LEFT JOIN sys .databases AS d
729+ ON id .database_name = d .name
730+ WHERE NOT EXISTS
731+ (
732+ SELECT
733+ 1 / 0
734+ FROM #databases AS db
735+ WHERE db .database_name = id .database_name
736+ )
737+ OPTION (RECOMPILE );
738+
739+ IF @debug = 1
740+ BEGIN
741+ SELECT
742+ table_name = ' #requested_but_skipped_databases' ,
743+ rbsd.*
744+ FROM #requested_but_skipped_databases AS rbsd
745+ OPTION (RECOMPILE );
746+ END ;
747+ END ;
748+
705749 /* Parse @exclude_databases comma-separated list */
706750 IF @get_all_databases = 1
707751 AND @exclude_databases IS NOT NULL
@@ -2993,24 +3037,80 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29933037 target_index_name,
29943038 superseded_info,
29953039 original_index_definition,
3040+ script,
29963041 index_size_gb,
29973042 index_rows,
29983043 index_reads,
29993044 index_writes
30003045 )
30013046 SELECT
30023047 result_type = ' SUMMARY' ,
3003- sort_order = 1 ,
3004- database_name = ' ' ,
3005- schema_name = ' ' ,
3006- table_name = ' ' ,
3007- index_name = ' ' ,
3008- consolidation_rule = N ' ' ,
3009- script_type = ' Index Cleanup Scripts' ,
3048+ sort_order = - 1 ,
3049+ database_name =
3050+ N ' processed databases: ' +
3051+ CASE
3052+ WHEN @get_all_databases = 0
3053+ THEN ISNULL (@database_name, N ' None' )
3054+ ELSE
3055+ ISNULL
3056+ (
3057+ STUFF
3058+ (
3059+ (
3060+ SELECT
3061+ N ' , ' +
3062+ d .database_name
3063+ FROM #databases AS d
3064+ ORDER BY
3065+ d .database_name
3066+ FOR
3067+ XML
3068+ PATH (' ' ),
3069+ TYPE
3070+ ).value (' .' , ' nvarchar(max)' ),
3071+ 1 ,
3072+ 2 ,
3073+ N ' '
3074+ ),
3075+ N ' None'
3076+ )
3077+ END ,
3078+ schema_name =
3079+ N ' skipped databases: ' +
3080+ ISNULL
3081+ (
3082+ STUFF
3083+ (
3084+ (
3085+ SELECT
3086+ N ' , ' +
3087+ rbs .database_name +
3088+ N ' (' +
3089+ rbs .reason +
3090+ N ' )'
3091+ FROM #requested_but_skipped_databases AS rbs
3092+ ORDER BY
3093+ rbs .database_name
3094+ FOR
3095+ XML
3096+ PATH (' ' ),
3097+ TYPE
3098+ ).value (' .' , ' nvarchar(MAX)' ),
3099+ 1 ,
3100+ 2 ,
3101+ N ' '
3102+ ),
3103+ N ' None'
3104+ ),
3105+ table_name = N ' brought to you by erikdarling.com' ,
3106+ index_name = N ' for support: https://code.erikdarling.com/' ,
3107+ consolidation_rule = N ' run date: ' + CONVERT (nvarchar (30 ), SYSDATETIME (), 120 ),
3108+ script_type = N ' Index Cleanup Scripts' ,
30103109 additional_info = N ' A detailed index analysis report appears after these scripts' ,
3011- target_index_name = ' ' ,
3012- superseded_info = ' ' ,
3013- original_index_definition = ' ' ,
3110+ target_index_name = N ' ALWAYS TEST THESE RECOMMENDATIONS' ,
3111+ superseded_info = N ' IN A NON-PRODUCTION ENVIRONMENT FIRST!' ,
3112+ original_index_definition = N ' please enjoy responsibly!' ,
3113+ script = N ' happy index cleaning!' ,
30143114 index_size_gb = 0 ,
30153115 index_rows = 0 ,
30163116 index_reads = 0 ,
@@ -4597,6 +4697,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
45974697 ON ia .database_id = ce .database_id
45984698 AND ia .object_id = ce .object_id
45994699 AND ia .index_id = ce .index_id
4700+ WHERE ia .index_id > 1
46004701 OPTION (RECOMPILE );
46014702
46024703 /* Return enhanced database impact summaries */
@@ -5166,7 +5267,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
51665267 THEN ' 0'
51675268 ELSE FORMAT (ISNULL (ir .index_writes , 0 ), ' N0' )
51685269 END ,
5169- ia .original_index_definition ,
5270+ original_index_definition =
5271+ CASE
5272+ WHEN ir .result_type = ' SUMMARY'
5273+ THEN N ' please enjoy responsibly!'
5274+ ELSE ia .original_index_definition
5275+ END ,
51705276 /* Finally show the actual script */
51715277 ir .script
51725278 FROM
@@ -5253,8 +5359,22 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52535359 END ,
52545360
52555361 /* Schema and table names (except for summary) */
5256- schema_name = ISNULL (irs .schema_name , ' N/A' ),
5257- table_name = ISNULL (irs .table_name , ' N/A' ),
5362+ schema_name =
5363+ CASE
5364+ WHEN irs .summary_level = ' SUMMARY'
5365+ THEN ISNULL (irs .schema_name , ' ALWAYS TEST THESE RECOMMENDATIONS' )
5366+ WHEN irs .summary_level = ' DATABASE'
5367+ THEN N ' N/A'
5368+ ELSE irs .schema_name
5369+ END ,
5370+ table_name =
5371+ CASE
5372+ WHEN irs .summary_level = ' SUMMARY'
5373+ THEN ISNULL (irs .table_name , ' IN A NON-PRODUCTION ENVIRONMENT FIRST!' )
5374+ WHEN irs .summary_level = ' DATABASE'
5375+ THEN N ' N/A'
5376+ ELSE irs .table_name
5377+ END ,
52585378
52595379 /* ===== Section 1: Index Counts ===== */
52605380 /* Tables analyzed (summary only) */
@@ -5375,9 +5495,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
53755495 /* Total writes */
53765496 writes =
53775497 CASE
5498+ WHEN irs .summary_level = ' SUMMARY'
5499+ THEN ' N/A'
53785500 WHEN irs .summary_level <> ' SUMMARY'
53795501 THEN FORMAT (ISNULL (irs .total_writes , 0 ), ' N0' )
5380- ELSE ' N/A '
5502+ ELSE ' 0 '
53815503 END ,
53825504
53835505 /* Write operations saved - added as new metric */
@@ -5443,10 +5565,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
54435565 /* Total count of lock waits (row + page) */
54445566 lock_wait_count =
54455567 CASE
5568+ WHEN irs .summary_level = ' SUMMARY'
5569+ THEN ' N/A'
54465570 WHEN irs .summary_level <> ' SUMMARY'
54475571 THEN FORMAT (ISNULL (irs .row_lock_wait_count , 0 ) +
54485572 ISNULL (irs .page_lock_wait_count , 0 ), ' N0' )
5449- ELSE ' N/A '
5573+ ELSE ' 0 '
54505574 END ,
54515575
54525576 /* Lock waits saved - new column */
@@ -5512,6 +5636,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
55125636 /* Average lock wait time in ms */
55135637 avg_lock_wait_ms =
55145638 CASE
5639+ WHEN irs .summary_level = ' SUMMARY'
5640+ THEN ' N/A'
55155641 WHEN irs .summary_level <> ' SUMMARY'
55165642 AND (ISNULL (irs .row_lock_wait_count , 0 ) +
55175643 ISNULL (irs .page_lock_wait_count , 0 )) > 0
@@ -5525,10 +5651,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
55255651 /* Total count of latch waits (page + io) - new column */
55265652 latch_wait_count =
55275653 CASE
5654+ WHEN irs .summary_level = ' SUMMARY'
5655+ THEN ' N/A'
55285656 WHEN irs .summary_level <> ' SUMMARY'
55295657 THEN FORMAT (ISNULL (irs .page_latch_wait_count , 0 ) +
55305658 ISNULL (irs .page_io_latch_wait_count , 0 ), ' N0' )
5531- ELSE ' N/A '
5659+ ELSE ' 0 '
55325660 END ,
55335661
55345662 /* Latch waits saved - new column */
@@ -5594,17 +5722,18 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
55945722 /* Combined latch wait time in ms */
55955723 avg_latch_wait_ms =
55965724 CASE
5725+ WHEN irs .summary_level = ' SUMMARY'
5726+ THEN ' N/A'
55975727 WHEN irs .summary_level <> ' SUMMARY'
55985728 AND (ISNULL (irs .page_latch_wait_count , 0 ) +
55995729 ISNULL (irs .page_io_latch_wait_count , 0 )) > 0
56005730 THEN FORMAT (1 .0 * (ISNULL (irs .page_latch_wait_in_ms , 0 ) +
56015731 ISNULL (irs .page_io_latch_wait_in_ms , 0 )) /
56025732 NULLIF (ISNULL (irs .page_latch_wait_count , 0 ) +
56035733 ISNULL (irs .page_io_latch_wait_count , 0 ), 0 ), ' N2' )
5604- ELSE ' N/A '
5734+ ELSE ' 0 '
56055735 END
56065736 FROM #index_reporting_stats AS irs
5607- WHERE irs .summary_level IN (' SUMMARY' , ' DATABASE' , ' TABLE' ) /* Filter out INDEX level */
56085737 ORDER BY
56095738 /* Order by database name */
56105739 irs .database_name ,
0 commit comments