-1

I'm shrinking databases that are already on a SQL Elastic Pool.

The goal is to fit as much as possible databases in a unique Elastic Pool.

In order to do so I've stubble upon a blog that suggest to run this query which basically does 3 things:

  1. -- Step 1: Rebuild all the indexes
  2. -- Step 2: Shrink the database
  3. -- Step 3: Rebuild all the indexes

Here comes the query:

create or alter procedure [#ForEachTable](@inputStmt nvarchar(max))
as
begin
    set nocount, xact_abort on;
    drop table if exists [#Tables];

    select concat(quotename([S].[name]), N'.', quotename([T].[name])) as [table]
    into [#Tables]
    from [sys].[schemas] as [S]
        inner join [sys].[tables] as [T]
            on [S].[schema_id] = [T].[schema_id]
    where [T].[is_ms_shipped] = 0;

    declare tables cursor local fast_forward for select [table] from [#Tables];
    open tables;

    declare @table nvarchar(max);
    fetch next from tables into @table;

    declare @total integer = (select count(*) from [#Tables]);
    declare @space integer = len(cast(@total as nvarchar(max)));
    declare @current integer = 1;
    while @@fetch_status = 0
    begin
        declare @stmt nvarchar(max) = replace(@inputStmt, N'?', @table);
        
        declare @msg nvarchar(max) = concat(
            sysutcdatetime(), N' - ',
            N'[', right(concat(N'000', @current), @space), N'/', @total, N']: ',
            N'Executing command: "', @stmt, N'".'
        );
        raiserror(@msg, 10, 1) with nowait;

        execute [sys].[sp_executesql] @stmt = @stmt;
    
        fetch next from tables into @table;
        set @current += 1;
    end;

    close tables;
    deallocate tables;
end;
go

-- Step 1: Rebuild all the indexes
raiserror(N'First rebuild...', 10, 1) with nowait;
execute [#ForEachTable] N'alter index all on ? rebuild with (online = on);';
go

-- Step 2: Shrink the database
raiserror(N'Shrink...', 10, 1) with nowait;
declare @stmt nvarchar(max) = concat(N'dbcc shrinkdatabase (', db_id(), N')');
execute [sys].[sp_executesql] @stmt = @stmt;
go

-- Step 3: Rebuild all the indexes
raiserror(N'Final rebuild...', 10, 1) with nowait;
execute [#ForEachTable] N'alter index all on ? rebuild with (online = on);';

But after sever hours I receive this warning message and then SSMS shut down:

First rebuild...
2023-06-06 07:39:50.2128129 - [0001/1467]: Executing command: "alter index all on [dbo].[xhisto_2018] rebuild with (online = on);".
2023-06-06 07:39:50.2440440 - [0002/1467]: Executing command: "alter index all on [dbo].[Affiliate] rebuild with (online = on);".
2023-06-06 07:39:50.2596849 - [0003/1467]: Executing command: "alter index all on [dbo].[template_step] rebuild with (online = on);".
2023-06-06 07:39:50.2753131 - [0004/1467]: Executing command: "alter index all on [dbo].[mapping_monthly] rebuild with (online = on);".
2023-06-06 07:39:50.7596876 - [0005/1467]: Executing command: "alter index all on [dbo].[statement] rebuild with (online = on);".
2023-06-06 07:39:50.7753120 - [0006/1467]: Executing command: "alter index all on [dbo].[history] rebuild with (online = on);".
2023-06-06 07:39:50.7753120 - [0007/1467]: Executing command: "alter index all on [dbo].[formula_items] rebuild with (online = on);".
2023-06-06 07:39:50.7909373 - [0008/1467]: Executing command: "alter index all on [dbo].[monthly_staging] rebuild with (online = on);".
2023-06-06 07:39:50.8221873 - [0009/1467]: Executing command: "alter index all on [dbo].[sales] rebuild with (online = on);".
Msg 121, Level 20, State 0, Line 82
A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The semaphore timeout period has expired.)

Completion time: 2023-06-06T15:21:35.2092836+02:00

I'm running the query from SSMS installed on a VM on Azure. Quite sure it cannot be connectivity problems. This happens 1 time out of 2.

1 Answer 1

0

The semaphore problem was caused by the connection cut form the VDI, on which I had SSMS, and the Azure SQL Database.

there is no point ot reinvent the wheel. Microsoft propose an out-of-the-box solution for Azure SQL Database: Auto-shrink

-- Enable auto-shrink for the current database.
ALTER DATABASE CURRENT SET AUTO_SHRINK ON;

enter image description here

This made the trick.

If you then want to rebuild the indexes, once again, there is no point to reinvent the wheel. Microsoft propose Rebuilding SQL Database indexes using Azure Automation

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.