【问题标题】:SQL Server: how to write an alter index statement to add a column to the unique index?SQL Server:如何编写更改索引语句以将列添加到唯一索引?
【发布时间】:2012-04-03 17:32:59
【问题描述】:

我在当前使用 4 列作为索引的表上有一个 UNIQUE, NON CLUSTERED 索引。

我想创建一个更改脚本,它只能向该索引添加另一列。新的列类型是varchar

数据库是 SQL Server 2005。

提前致谢。

【问题讨论】:

  • 我确定我遗漏了一些东西,但你为什么不能只使用DROP INDEX Table.<Index>; CREATE UNIQUE INDEX <Index> ON Table (Col1, Col2, Col3, Col4)
  • @Lieven,我也在考虑这个问题。是否可以安全地 DROP 然后用表中的现有数据创建索引?
  • 是的。您可以随意删除和创建索引。您可能会注意到在索引消失时执行查询的性能下降,但删除和创建(非聚集)索引对存储在表中的实际数据没有任何影响(创建聚集索引会影响数据的物理顺序,但同样没有数据丢失)

标签: sql-server-2005 indexing alter


【解决方案1】:

我可能迟到了 9 年,但我就是这样做的(这会删除现有索引并使用列表中的列创建新索引):

CREATE UNIQUE NONCLUSTERED INDEX [INDEX_NAME] ON [TABLE_NAME]
(
    [COLUMN1] DESC,
    [COLUMN2] ASC
) 
WITH
(
    PAD_INDEX = OFF,
    STATISTICS_NORECOMPUTE = OFF,
    SORT_IN_TEMPDB = OFF,
    IGNORE_DUP_KEY = ON,
    DROP_EXISTING = ON,
    ONLINE = OFF,
    ALLOW_ROW_LOCKS = ON,
    ALLOW_PAGE_LOCKS = ON
) 
ON [PRIMARY]

【讨论】:

    【解决方案2】:

    我希望更改索引意味着首先我们必须删除索引并再次创建索引

    语法:

    if exists
    (
    select * from sys.indexes where name ='ix_name'
    )
    BEGIN
    DROP INDEX Table.index name
    END
    
    IF NOT EXISTS
    (
    select * from sys.indexes where name ='ix_name'
    )
    BEGIN
    CREATE NONCLUSTERED INDEX 
    ON TABLENAME
    (
    COLUMN1,
    COLUMN2,
    COLUMN3,
    COLUMN4,
    --Whatever column u want to add
    )
    end
    go
    

    【讨论】:

      【解决方案3】:

      你不能改变一个索引——你能做的就是

      1. 删除旧索引 (DROP INDEX (indexname) ON (tablename))

      2. 重新创建包含附加列的新索引:

           CREATE UNIQUE NONCLUSTERED INDEX (indexname)
           ON dbo.YourTableName(columns to include)
        

      SQL Server 中的ALTER INDEX 语句(请参阅docs)可用于更改现有索引的某些属性(存储属性等),但它不允许更改构成索引的列。

      【讨论】:

      • 感谢 Marc,您提出的解决方案有效,并且脚本得到了我们团队中 DBA 的批准。
      • 现在你把我难住了......如果你的团队中有 DBA,为什么还要问这个问题?
      • 查看 MSDN 上创建索引页面中的 DROP_EXISTING。在某些限制下,您可以修改索引。请参阅此处 Paul White 的回复。 sqlservercentral.com/Forums/Topic913722-391-1.aspx
      • @LievenKeersmaekers why ask the question if you have DBA's on your team? 对于有同样问题的人,也许? StackOverflow 的总体用途?
      • @LievenKeersmaekers - Code First ~ 应该在迁移中维护索引。用非 sql 语言编写的迁移。程序员编写迁移,而不是 DBA
      【解决方案4】:

      如果您要添加到索引的新列位于列列表的末尾 - 换句话说,如果旧索引的列列表是新索引的列列表的前缀 - 那么行按旧列排序的仍将按新列排序。在 Sybase SQL Server 以及可能是旧版本的 Microsoft SQL Server 中,有一个 with sorted_data 选项可让您声明行已排序。但在 MSSQL 2008 R2 上似乎没有效果;该选项被接受但默默地忽略。无论如何,我认为该选项对聚集索引最有用。

      其他人提到了with drop_existing,这听起来不错,但仅适用于更昂贵的 MSSQL 版本。

      【讨论】:

      • 你从哪里得到with sorted_data?我没有看到sorted_data 被列为withcreate index 语句的create index 语句在该语句的SQL Server 2008+ 文档中(在:link)。
      • with sorted_data 是我对过去 Sybase SQL Server 的记忆。 Microsoft 删除了 Sybase 支持的一些时髦的索引创建选项,但没有删除这个选项。然而,对 MSSQL 2008 R2 的快速实验表明它现在可能是空操作;如果表中的数据未排序,则不会给出错误。所以我会修改我的答案。
      • 快速搜索显示该选项已记录在 MSSQL 2000 中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-19
      • 1970-01-01
      • 1970-01-01
      • 2015-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多