2013-05-14 81 views
6

我必须将我的DB放入bacpac文件以将其导入到Azure中。 当我尝试导出时,我得到一个错误,因为任何索引都有一个fillFactor值。Sql Server通过tsql更改所有索引的填充因子值

我发现如何为所有索引设置fillFactor值,但我不能指定0,值必须在1和100之间。如果我在管理工作室中更改了值,我可以将其设置为0

问题是我有很多索引要更改,我想通过tsql将fillFactor值更改为所有索引。

有什么想法?

谢谢。

回答

-2
ALTER INDEX yourindex ON table.column 
REBUILD WITH (FILLFACTOR = 0); 

完成这项工作。 0等于100(参见http://msdn.microsoft.com/en-us/library/ms177459.aspx),这意味着索引中没有剩余空位。

你必须为每个索引运行这个。但重建可能需要相当长的时间。

+2

如果我尝试fillfactor = 0,我得到这个消息:Fillfactor 0不是有效的百分比; fillfactor必须在1到100之间。我将它设置为0以便能够将我的数据库导出到bacpac中。 – danielUrrero 2013-05-15 08:08:39

+0

将其设置为0不起作用(1至100之间的任何数字) – Rodney 2014-03-24 09:56:29

+0

只是为了理解您的要求:为什么要将其设置为0? – 2014-03-26 10:13:13

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 
+2

谢谢,这是我使用的tsql,但问题是0在“set @ fillfactor = 0”中无效。 – danielUrrero 2013-05-15 08:05:29

+0

'0'是默认值,意味着索引被填满到满容量,等于'100'('Fillfactor'单位是百分比)。你尝试将它设置为100,然后导出到'.bacpac'? – 2013-05-15 09:33:35

+1

是的,我试过了,不支持。 – danielUrrero 2013-05-16 10:55:26

1

SQL Azure的显然不支持FILLFACTOR

"SQL Azure Database does not support specifying FILLFACTOR with the CREATE INDEX statement. If we create indexes in a SQL Azure database, we will find that the index fillfactor values are all 0."

你将不得不删除所有来自CREATE INDEX脚本的FILLFACTOR声明。同样,SORT_IN_TEMPDBDATA_COMPRESSION和其他几个选项也不受支持。

SQL Azure支持的关键字的完整列表可以在here找到。

更新:SQL Azure的V12(2015年推出)确实支持FILLFACTOR。见here

1

这不是一个直接的T-SQL方式。尽管它确实生成了可应用于数据库的纯T-SQL解决方案。

您的结果可能取决于你的DB变化......例如贫穷参照完整性可能使这有点棘手..

而且这种带有一个请自行风险免责:-)

  1. 获取要迁移到SSDT项目

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

的DB

这是将任何模式迁移到Azure的好方法,无论如何...它更好,然后只是创建一个bacpac文件..修复...出口...修复..等等...所以我会建议这样做,只要你想将数据库迁移到Azure

对于FILLFACTOR修复我只是使用的查找和替换从生成的模式文件中删除所有的填充因子......幸运的是,我用了所有这些设置为90,这是很容易做到的解决方案数据库广泛查找和替换(CTRL-SHIFT-F )...如果你有所不同,那么你可以使用Visual Studio的RegEx查找功能来查找所有的fillfactors,并将它们从索引中删除。

我不是在正则表达式是伟大的,但我想这样的作品

WITH \((.)*FILLFACTOR(.)*\) 

此时你就必须解决围绕Azure的遵守任何其他例外..提供的链接描述了如何去这样做这

  1. 现在您已经达到了符合AZURE SQL标准的SSDT项目。

这里谈到的DO风险自负部分

我使用这些脚本删除所有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项目,做对你的DB该项目的模式比较...这将创建再现所有的FK的一个剧本, PK的,和唯一约束(不填充因子)......在这一点上,你可以点击“更新”,或者你可以点击按钮即可更新,这将产生你可以使用脚本正确的...所以现在与

    • 脚本武装以上来删除FK,Pks和Unique。
    • 通过SSDT创建的脚本
    • 充足的测试,说脚本,以确保没有被错过
  • 你应该能够更新当前DB到Azure的兼容SCHEMA

    审查其他想法:

    在我的情况下,生产数据库上的填充因子并不是真的在做任何事情g有用。他们只是被创建为一个默认的事情。在你的情况下,填充因子可能很重要,所以不要在不知道结果的情况下将它们全部移除到非Azure生产框中。

    有额外的东西这样做是为了在生产系统时需要考虑的......例如,这可能会导致某些镜像延迟,则可能会导致你的日志文件中的你是不是期待的方式成长。如果你直接应用于生产,这两者都是非常重要的。

    它会是不错的,如果将它们设置所有填充因子100工作: -/

    有第三方工具,在那里(所以我听说),您可以使用迁移到Azure的...

    另一种选择是使用 https://sqlazuremw.codeplex.com/

    用它来创建一个模式,它的Azure兼容的,然后它使用BCP复制所有数据。

    但是如果你想让你当前的SCHEMA Azure兼容,那么你可以创建一个bacpac文件上传到Azure,这对我来说是一次不得不做的工作。

    编辑: Azure的V12支持填充因子

    0

    看来你要使用的服务器默认的填充因子(0),它省略了从创作剧本的FILLFACTOR声明。没有办法通过重建索引来完成此操作,您必须删除并重新创建索引(请参阅here)。目前似乎还没有一种干净的方式来做到这一点,尽管它现在是一个有争议的问题。

    0

    简单的所有表的东西在一个单一的数据库:

    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 
    

    生成报表可以然后复制&执行。