【问题标题】:What key columns to use on filtered index with covering WHERE clause?使用覆盖 WHERE 子句的过滤索引上使用哪些键列?
【发布时间】:2014-04-16 22:51:23
【问题描述】:

我正在创建一个过滤索引,以便 WHERE 过滤器包含完整的查询条件。有了这样的索引,似乎不需要键列,尽管 SQL 要求我添加一个。例如,考虑表格:

CREATE TABLE Invoice
(
    Id INT NOT NULL IDENTITY PRIMARY KEY,
    Data VARCHAR(MAX) NOT NULL,
    IsProcessed BIT NOT NULL DEFAULT 0,
    IsInvalidated BIT NOT NULL DEFAULT 0
)

表格上的查询查找要处理的新发票,即:

SELECT *
FROM Invoice
WHERE IsProcessed = 0 AND IsInvalidated = 0

所以,我可以使用过滤索引来调整这些查询:

CREATE INDEX IX_Invoice_IsProcessed_IsInvalidated
ON Invoice (IsProcessed)
WHERE (IsProcessed = 0 AND IsInvalidated = 0)
GO

我的问题:IX_Invoice_IsProcessed_IsInvalidated 的键列应该是什么?大概没有使用键列。我的直觉使我选择了一个较小的列,并使索引结构保持相对平坦。我应该选择表主键(Id)吗?过滤器列之一,还是两者都?

【问题讨论】:

  • 您是否尝试过查看针对没有索引的表的查询的执行计划,以了解建议的索引方式?
  • 在测试您的表并查看执行计划后,没有建议索引,我怀疑这是因为您没有从位列索引中获得太多好处。这个问题似乎支持stackoverflow.com/questions/231125/…
  • @Tanner:我查看了执行计划。查询优化器在索引中的行数与表中的总行数相比较小的条件下选择索引(预期场景)。我的问题是关于如何优化索引的效率(大小、I/O)。

标签: sql sql-server sqlperformance filtered-index


【解决方案1】:

这个过滤索引覆盖了多少百分比的表?如果它很小,您可能希望覆盖整个表以处理索引中的“SELECT *”而不碰到表。如果它是表格的很大一部分,尽管这不是最佳选择。然后我建议使用聚集索引或主键。我必须进行更多研究,因为我忘记了现在哪个是最佳的,但如果它们相同,则应该设置。

【讨论】:

  • 索引中的行数与表中的总行数相比是很小的,这就是我选择过滤索引的原因。您能否详细说明为什么要使用聚集索引/主键? “最佳”是什么意思?
【解决方案2】:

因为您在该表上有一个聚集索引,所以您在该索引的键列中放入什么并不重要;意思是Id 是免费的。您唯一能做的就是include 索引的包含部分中的所有内容,以便在索引的叶级别实际拥有方便的数据,以排除对表的键查找。或者,如果队列很大,那么关键部分中的其他列可能会很有用。

现在,如果该表没有主键,那么您将不得不 include 或将您需要用于连接或其他目的的所有列指定为键列。否则,将发生堆上的 RID 查找,因为在索引的叶级别上,您将引用数据页。

【讨论】:

    【解决方案3】:

    我建议你声明如下

    CREATE INDEX IX_Invoice_IsProcessed_IsInvalidated
    ON Invoice (Id)
    INCLUDE (Data)
    WHERE (IsProcessed = 0 AND IsInvalidated = 0)
    

    INCLUDE 子句意味着数据列的值将作为索引的一部分存储。

    如果您没有 INCLUDE 子句,则查询计划为

    SELECT Id, Data
    FROM Invoice
    WHERE IsProcessed = 0 AND IsInvalidated = 0
    

    将涉及两步过程

    • 使用索引查找匹配的主键值列表 标准
    • 从表中获取与那些主键匹配的数据

    另一方面,如果索引包含 [Data] 列,那么它将正确覆盖查询,因为无需使用主键查找数据

    尽管如此,你不会得到任何东西

    这样做的缺点是您将为这些记录存储两次 varchar(MAX) 数据,因此需要将更多数据写入数据库并使用更多存储空间,尽管这不是一个如果您只讨论一小部分数据,则会出现问题。

    与往常一样,您在小心地收起东西上投入的时间和精力越多,取回它们就越快、越容易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-01
      • 1970-01-01
      • 2012-06-20
      • 1970-01-01
      • 2012-06-03
      • 1970-01-01
      相关资源
      最近更新 更多