【问题标题】:Should I delete Hypothetical Indexes?我应该删除假设索引吗?
【发布时间】:2014-01-14 11:03:41
【问题描述】:

我注意到某个数据库中存在假设索引。我搜索了一下,似乎这种类型的索引是由Tuning Advisor 创建的,并不总是被删除。

有几个主题,包括official 说明如何清除/删除这些索引的文档,但我无法找到这些索引是否对服务器本身有任何影响。

我使用下面的脚本检查的是没有关于它们的大小信息:

SELECT OBJECT_NAME(I.[object_id]) AS TableName
      ,I.[name] AS IndexName
      ,I.[index_id] AS IndexID
      ,8 * SUM(A.[used_pages]) AS 'Indexsize(KB)'
FROM [sys].[indexes] AS I
INNER JOIN [sys].[partitions] AS P 
    ON P.[object_id] = I.[object_id] 
    AND P.[index_id] = I.[index_id]
INNER JOIN [sys].[allocation_units] AS A 
    ON A.[container_id] = P.[partition_id]
WHERE I.[is_hypothetical] = 1
GROUP BY I.[object_id]
        ,I.[index_id]
        ,I.[name]
ORDER BY 8 * SUM(A.[used_pages]) DESC

有了它们,我决定检查是否有一些关于它们的使用信息,以便留下经常使用的这些,但再次没有返回。 (我使用了来自this article 的“现有索引使用统计信息”)。

谁能告诉我为什么保留这些索引是错误的,我是否可以定义应该保留哪些?

【问题讨论】:

  • 它们不占用任何空间,除了元数据并且应该被 QO 忽略,除非 DBCC AUTOPILOT 运行。所以理论上它们不应该造成太大的伤害。你为什么不把它们清理干净呢?即使它们对 SQL Server 的影响不大,它们的存在也可能会导致第三方脚本出现问题。
  • @MartinSmith 非常感谢。只是出于好奇,您能否提供一个此类问题情况的示例?

标签: tsql sql-server-2012 database-tuning-advisor


【解决方案1】:

只需USE您要清理并运行的数据库即可:

DECLARE @sql VARCHAR(MAX) = ''

SELECT
    @sql = @sql + 'DROP INDEX [' + i.name + '] ON [dbo].[' + t.name + ']' + CHAR(13) + CHAR(10)
FROM 
    sys.indexes i 
    INNER JOIN sys.tables t 
        ON i.object_id = t.object_id 
WHERE 
    i.is_hypothetical = 1


EXECUTE sp_sqlexec @sql

【讨论】:

    【解决方案2】:

    只需删除它们,它们实际上不会占用任何空间或导致任何性能损失/好处,但如果您正在查看在表上定义了哪些索引并且忘记排除假设索引,则可能会导致一些混乱,即使您尝试创建与这些索引之一同名的索引,它也会失败,因为它已经存在。

    【讨论】:

    • 我已经删除了它们,但请注意,当索引被删除时,一个表被锁定,这给我带来了很多问题。
    【解决方案3】:

    如果您使用自定义架构并检查分析索引视图,则需要对上述脚本进行一些进一步的改进:

    DECLARE     @sql VARCHAR(MAX) = ''
    
    SELECT      @sql = @sql 
                + 'DROP INDEX [' + i.name + ']'
                + 'ON [' + OBJECT_SCHEMA_NAME(t.[object_id]) + '].[' + t.name + ']' 
                + CHAR(13) + CHAR(10)
    FROM        sys.indexes i 
    INNER JOIN  sys.[all_objects] t 
    ON          i.object_id = t.object_id 
    WHERE       i.is_hypothetical = 1
    
    PRINT       @sql
    
    EXECUTE     sp_sqlexec @sql
    

    【讨论】:

    • 在处理索引时我永远不会运行自动脚本。
    猜你喜欢
    • 1970-01-01
    • 2011-06-21
    • 2014-10-18
    • 2013-01-03
    • 2017-03-19
    • 2010-09-21
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多