我正在缩小 SQL 弹性池上已有的数据库。
目标是在一个独特的弹性池中容纳尽可能多的数据库。
为了做到这一点,我偶然发现了一个博客,建议运行这个查询,它基本上做了三件事:
- -- 步骤1:重建所有索引
- -- 第 2 步:收缩数据库
- -- 步骤3:重建所有索引
查询来了:
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);';
但几个小时后我收到此警告消息,然后 SSMS 关闭:
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
我正在从安装在 Azure 上的 VM 上的 SSMS 运行查询。非常肯定这不可能是连接问题。这种情况发生二分之一。
信号量问题是由 VDI(我在其上有 SSMS)和 Azure SQL 数据库的连接中断引起的。
重新发明轮子是没有意义的。微软为Azure SQL数据库提出了一个开箱即用的解决方案:自动收缩
这就成功了。
如果您想再次重建索引,则没有必要重新发明轮子。微软建议使用 Azure 自动化重建 SQL 数据库索引