我必须将我的数据库导出到一个 bacpac 文件中才能将其导入 Azure。当我尝试导出时,我得到一个错误,因为任何索引都有一个 fillFactor 值。
我找到了如何为所有索引设置一个 fillFactor 值,但我不能指定 0,该值必须在 1 到 100 之间。如果我在管理工作室中更改该值,我可以将其设置为 0。
问题是我有很多索引要更改,我想通过 tsql 将 fillFactor 值更改为所有索引。
有任何想法吗?。
谢谢。
我必须将我的数据库导出到一个 bacpac 文件中才能将其导入 Azure。当我尝试导出时,我得到一个错误,因为任何索引都有一个 fillFactor 值。
我找到了如何为所有索引设置一个 fillFactor 值,但我不能指定 0,该值必须在 1 到 100 之间。如果我在管理工作室中更改该值,我可以将其设置为 0。
问题是我有很多索引要更改,我想通过 tsql 将 fillFactor 值更改为所有索引。
有任何想法吗?。
谢谢。
对于单个数据库中的所有表来说更简单:
select 'ALTER INDEX ALL ON ['
+ s.name+ '].['+ o.name+'] REBUILD WITH (FILLFACTOR = 99)'
from sys.objects o
inner join sys.schemas s on o.schema_id = s.schema_id
where type='u' and is_ms_shipped=0
生成您可以复制和执行的语句。
这不是一种直接的 T-SQL 方式。虽然它确实生成了一个纯 T-SQL 解决方案,您可以将其应用于您的数据库。
您的结果可能会因您的数据库而异......例如,较差的参照完整性可能会使这有点棘手......
这还附带一个您自己承担风险的免责声明:-)
http://msdn.microsoft.com/en-us/library/azure/jj156163.aspx http://blogs.msdn.com/b/ssdt/archive/2012/04/19/migrating-a-database-to -sql-azure-using-ssdt.aspx
这是将任何架构迁移到 Azure 的好方法……这比创建一个 bacpac 文件要好得多……修复……导出……修复……等等……所以我建议你随时这样做将数据库迁移到 Azure
对于 FILLFACTOR 修复,我只是使用查找和替换从生成的模式文件中删除所有 FILLFACTORS...幸运的是,我使用的数据库将它们全部设置为 90,因此很容易进行解决方案范围的查找和替换( CTRL-SHIFT-F)...如果您的不同,那么您可以使用 Visual Studio 的 RegEx 查找功能来查找所有填充因子,然后将它们从索引中删除。
我在 RegEx 方面不是很好,但我认为这很有效
WITH \((.)*FILLFACTOR(.)*\)
此时,您必须修复有关 Azure 合规性的任何其他异常。提供的链接描述了如何执行此操作
风险自负的部分来了
我使用这些脚本从数据库中删除了所有 FK、PK 和唯一约束。
while(exists(select 1 from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where CONSTRAINT_TYPE IN ('FOREIGN KEY', 'PRIMARY KEY', 'UNIQUE')))
begin
declare @sql nvarchar(2000)
SELECT TOP 1 @sql=('ALTER TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME
+ '] DROP CONSTRAINT [' + CONSTRAINT_NAME + ']')
FROM information_schema.table_constraints
WHERE CONSTRAINT_TYPE IN ('FOREIGN KEY', 'PRIMARY KEY', 'UNIQUE')
exec (@sql)
end
declare @qry nvarchar(max);
select @qry =
(SELECT 'DROP INDEX [' + ix.name + '] ON [' + OBJECT_NAME(ID) + ']; '
FROM sysindexes ix
WHERE ix.Name IS NOT null and ix.OrigFillFactor <> 0
for xml path(''));
exec sp_executesql @qry
我这样做是因为 AFAIK 完全删除填充因子选项的唯一方法是删除并重新创建索引。这带来了一系列级联问题:-/具有填充因子的 PK 需要删除 FK 等......可能有一种更聪明的方法可以做到这一点,这样您就不会删除所有 FK 和 PK,而是查看依赖关系树。 ..
现在回到您的 Azure 兼容 SSDT 项目,并对该项目与您的数据库进行 SCHEMA 比较...这将创建一个脚本,重新创建您的所有 FK、PK 和唯一约束(没有填充因子)...在此时您可以单击“更新”,或者您可以单击更新右侧的按钮,这将生成您可以使用的脚本......所以现在有了
您应该能够将当前数据库更新为符合 Azure 的 SCHEMA
其他想法:
在我的情况下,生产数据库上的填充因子并没有真正做任何有用的事情。它们只是作为默认操作创建的。在您的情况下,填充因子可能很重要,因此不要在不知道后果的情况下将它们全部删除到您的非 Azure 生产盒中。
对生产系统执行此操作时,还需要考虑其他事项...例如,这可能会导致一些镜像延迟,并且可能会导致您的日志文件以您未预料到的方式增长。只有当你直接应用于生产时,这两者才真正重要......
如果将它们全部设置为 FILL FACTOR 100 工作,那就太好了:-/
那里有第 3 方工具(所以我听说过)可用于迁移到 Azure ......
另一种选择是使用 https://sqlazuremw.codeplex.com/
使用它来创建符合 Azure 的 SCHEMA,然后它使用 BCP 复制所有数据。
但是,如果您想让您当前的 SCHEMA Azure 兼容,那么您可以创建一个 bacpac 文件以上传到 Azure,这对我来说是一次我必须这样做的工作。
编辑: Azure V12 支持填充因子
SQL Azure 显然不支持FILLFACTOR
:
“SQL Azure 数据库不支持用 CREATE INDEX 语句指定 FILLFACTOR。如果我们在 SQL Azure 数据库中创建索引,我们会发现索引的填充因子值都是 0。”
您必须从脚本中删除所有FILLFACTOR
语句。CREATE INDEX
同样,也不支持SORT_IN_TEMPDB
and和其他几个选项。DATA_COMPRESSION
可以在此处找到 SQL Azure 中支持的关键字的完整列表。
更新:SQL Azure V12(2015 年推出)确实支持FILLFACTOR
. 见这里。
我在这里找到了一个非常有用的脚本,它可以为所有索引分配一个新值并重建它们。只要您不害怕使用动态 T-SQL,您可能会发现它对您的任务和环境很有用,只需适当地设置值即可。(我在原始页面上没有找到许可证信息,所以我在这里复制脚本)
DECLARE @Database VARCHAR(255)
DECLARE @Table VARCHAR(255)
DECLARE @cmd NVARCHAR(500)
DECLARE @fillfactor INT
SET @fillfactor = 90
DECLARE DatabaseCursor CURSOR FOR
SELECT name FROM master.dbo.sysdatabases
WHERE name NOT IN ('master','msdb','tempdb','model','distribution')
ORDER BY 1
OPEN DatabaseCursor
FETCH NEXT FROM DatabaseCursor INTO @Database
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = 'DECLARE TableCursor CURSOR FOR SELECT ''['' + table_catalog + ''].['' + table_schema + ''].['' +
table_name + '']'' as tableName FROM [' + @Database + '].INFORMATION_SCHEMA.TABLES
WHERE table_type = ''BASE TABLE'''
-- create table cursor
EXEC (@cmd)
OPEN TableCursor
FETCH NEXT FROM TableCursor INTO @Table
WHILE @@FETCH_STATUS = 0
BEGIN
IF (@@MICROSOFTVERSION / POWER(2, 24) >= 9)
BEGIN
-- SQL 2005 or higher command
SET @cmd = 'ALTER INDEX ALL ON ' + @Table + ' REBUILD WITH (FILLFACTOR = ' + CONVERT(VARCHAR(3),@fillfactor) + ')'
EXEC (@cmd)
END
ELSE
BEGIN
-- SQL 2000 command
DBCC DBREINDEX(@Table,' ',@fillfactor)
END
FETCH NEXT FROM TableCursor INTO @Table
END
CLOSE TableCursor
DEALLOCATE TableCursor
FETCH NEXT FROM DatabaseCursor INTO @Database
END
CLOSE DatabaseCursor
DEALLOCATE DatabaseCursor
您似乎想使用服务器默认填充因子 (0),它忽略了FILLFACTOR
创建脚本中的语句。仅通过重建索引是无法做到这一点的,您必须删除并重新创建它(参见此处)。似乎没有一种干净的方法可以做到这一点,尽管它现在有点争议。
ALTER INDEX yourindex ON table.column
REBUILD WITH (FILLFACTOR = 0);
做这项工作。0 等于 100(请参阅http://msdn.microsoft.com/en-us/library/ms177459.aspx),这意味着索引中不会留下任何间隙。
你必须为每个索引运行它。不过,重建可能需要相当长的时间。