我必须将我的数据库暴露到bacpac文件中以将其导入Azure。 当我尝试导出时,我得到一个错误,因为任何索引都有一个fillFactor值。
我已经找到了如何为所有索引设置fillFactor值但是我不能指定0,值必须在1到100之间。如果我在管理工作室中更改了值,我可以将其设置为0。
问题是我有很多索引需要更改,我想通过tsql将fillFactor值更改为所有索引。
任何想法?。
感谢。
答案 0 :(得分:1)
SQL Azure显然不支持FILLFACTOR
:
您必须从FILLFACTOR
脚本中删除所有CREATE INDEX
语句。同样,也不支持SORT_IN_TEMPDB
和DATA_COMPRESSION
以及其他几个选项。
可以找到SQL Azure中支持的关键字的完整列表here。
更新:SQL Azure V12(2015年推出) 支持FILLFACTOR
。请参阅here。
答案 1 :(得分:1)
这不是一种直接的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修复,我只是使用了一个find和replace来从生成的模式文件中删除所有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&#39;然后查看依赖树...
现在回到您的Azure Compliant SSDT项目,并针对您的数据库执行该项目的SCHEMA COMPARISON ...这将创建一个脚本,重新创建您的所有FK,PK&#39; s,和唯一约束(没有填充因子)....此时你可以点击&#34;更新&#34;或者您可以单击更新右侧的按钮,这将生成您可以使用的脚本...所以现在配备
您应该能够将当前数据库更新为符合Azure的SCHEMA
其他想法:
在我的情况下,生产数据库中的填充因子并没有真正做任何有用的事情。它们只是作为默认设置创建的。在您的情况下,填充因子可能很重要,因此请不要在非Azure制作框中将其全部删除,而不知道其后果。
在对生产系统执行此操作时还需要考虑其他事项...例如,这可能会导致一些镜像延迟,并且可能会导致日志文件以您预期的方式增长。如果您直接申请生产,这两者都真的很重要......
如果将它们全部设置为FILL FACTOR 100,它会很好: - /
那里有第三方工具(我已经听说过)你可以用来迁移到Azure ......
另一种选择是使用 https://sqlazuremw.codeplex.com/
使用它来创建符合Azure的SCHEMA,然后使用BCP复制所有数据。
但是如果你想让你当前的SCHEMA Azure兼容,那么你可以创建一个bacpac文件上传到Azure,这对我来说只有一次我必须这样做。
修改强> Azure V12支持填充因子
答案 2 :(得分:1)
对于单个数据库中的所有表来说更简单:
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
生成您可以复制的语句&amp;执行。
答案 3 :(得分:0)
我找到了一个非常有用的脚本here,它可以为所有索引分配新值并重建它们。只要您不担心使用动态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
答案 4 :(得分:0)
似乎您想使用服务器默认填充因子(0),它忽略了创建脚本中的FILLFACTOR
语句。没有办法只重建索引,你必须删除并重新创建它(见here)。现在看起来并不是一种干净利落的方式,尽管现在它有点模棱两可。
答案 5 :(得分:-1)
ALTER INDEX yourindex ON table.column
REBUILD WITH (FILLFACTOR = 0);
完成这项工作。 0等于100(见http://msdn.microsoft.com/en-us/library/ms177459.aspx),表示索引中没有留下间隙。
你必须为每个索引运行它。但重建可能需要相当长的时间。