代码之家  ›  专栏  ›  技术社区  ›  Tom H

必须在表上重新生成两次索引

  •  1
  • Tom H  · 技术社区  · 15 年前

    我在一个全新的SQL 2005数据库中有一个表。作为应用程序部署的一部分,我们用大约2.6米的行加载表。完成后,表上的索引都将重新生成。然后让用户进入系统并针对该表进行查询超时。然后我可以重建索引(使用导入后使用的相同脚本),查询速度非常快。

    我已经检查了索引重建后表中没有其他主要数据更改。还有其他可能导致这种行为的想法吗?

    以下是索引重建脚本的示例:

    DROP INDEX dbo.My_Table.Index1
    DROP INDEX dbo.My_Table.Index2
    
    ALTER INDEX PK_My_Table ON dbo.My_Table REBUILD
    
    CREATE NONCLUSTERED INDEX Index1 ON dbo.My_Table (column_1 ASC)
    CREATE NONCLUSTERED INDEX Index2 ON dbo.My_Table (column_2 ASC)
    
    6 回复  |  直到 15 年前
        1
  •  1
  •   gbn    15 年前

    可能是统计数据,但不是关于索引的

    乐观者将获取第一个查询的更改行数/无统计信息。它决定重建/创建统计。

    但是:可能存在与索引无关的列级统计信息。

    第二次重新生成与stat无关,因为列stats已经存在,但它强制放弃并重新评估执行计划。

    编辑:

    SQLServerPedia :

    …列统计数据不会被 索引重建过程…

        2
  •  1
  •   RBarryYoung    15 年前

    我怀疑仅仅在第一次添加索引并不能重建统计数据。在加载表之后,尝试对其执行dbcc dbreindex。您还可能希望确保您有一个聚集索引。

        3
  •  1
  •   dlamblin    15 年前

    也许完成索引只需要很长时间。第一次索引重建后,您等待了多长时间?

    更新 :我看到这真的是一个周末的事情,这意味着索引第一次不能正常工作。在这种情况下,我没有任何建议超过目前所说的。

        4
  •  1
  •   Garrett    15 年前

    删除索引 之前 您可以批量插入数据。这样可以更快地插入数据。在加载数据之前,还要禁用相关表上的任何触发器。

    然后,添加索引。这样可以避免您当前正在进行的不必要的冗余索引重建。

    另外,正如一位用户已经指出的那样,使用dbcc dbreindex而不是删除和重新添加索引更有意义。你也可以 update statistics 当然。

    更新:由于dbcc dbreindex已被弃用(命令,而不是概念),请将alter index与rebuild选项一起使用。

        5
  •  0
  •   Josip Medved    15 年前

    我假设在您的导入过程中,某些东西会导致索引数据在许多数据页上分布。重建它们解决了这个问题。

        6
  •  0
  •   adrianbanks    15 年前

    我记得在某个地方读到过,SQL Server在创建索引时使用了当前的统计信息。如果统计数据过时,则可以针对错误的情况优化正在创建的索引,并给出性能不佳的结果。

    在创建索引之前,请尝试更新表上的统计信息。

    这个 UPDATE STATISTICS BOL中的条目表示可能发生这种情况:

    数据库引擎保存关于每个索引中键值分布的统计信息,并使用这些统计信息来确定在查询处理中要使用的索引。用户可以使用CREATE STATISTICS语句在非索引列上创建统计信息。查询优化取决于分发步骤的准确性:

    • 如果索引中的键值发生重大变化,请重新运行该索引的更新统计信息。
    • 如果索引列中的大量数据已被添加、更改或删除(即,如果键值的分布已更改),或者表已被使用truncate table语句截断,然后重新填充,请使用update statistics。

    因为您已经将数百万行导入到一个空表中,所以我认为您已经访问了上面的一个案例。