我创建了一个过滤索引(在 SQL Server 2012 中)并将其与非过滤索引进行了比较——我可以看到有希望的改进,如下所示。现在我需要更改过滤条件以使用表中的两列。所需条件是 WHERE InboundQuantity - OutboundQuantity <> 0
或 InboundQuantity <> OutboundQuantity
但是当我应用此过滤器时,我收到错误消息
“过滤索引 'IX_WO_PlantCD_FilterQtyNotEqual' 的 WHERE 子句不正确”。
我知道过滤索引有局限性。但是,有没有办法通过两列条件,使用过滤索引等来实现这种改进?
询问
--Normal Index
CREATE NONCLUSTERED INDEX IX_WO_NormalPlantCD
ON dbo.MyTable (PlantCD) INCLUDE (InboundQuantity,OutboundQuantity)
--Filtered Index
CREATE NONCLUSTERED INDEX IX_WO_PlantCD_FilterInboundQtyNotEqual
ON dbo.MyTable (PlantCD) INCLUDE (InboundQuantity,OutboundQuantity)
WHERE InboundQuantity <> 0
--Query 1
SELECT SUM([InboundQuantity] - [OutboundQuantity])
FROM [MyTable]
WHERE [PlantCD] = 'XX'
--Query2 (suing same where condition as filtered index)
SELECT SUM([InboundQuantity] - [OutboundQuantity])
FROM [MyTable]
WHERE [PlantCD] = 'XX'
AND InboundQuantity<>0
计划
如果计算列上的筛选索引过于有限,您可以选择创建索引视图。
索引视图由数据库自动维护,因此您无需担心所有可能的 DML 操作的触发逻辑是否正确。您也不必担心高并发下复杂的正确性问题。
维护视图索引的开销通常也比触发器少。
例如,给定一个表:
一个合适的索引视图可能是:
如果您正在运行企业版,自动索引视图匹配意味着在不直接引用视图的情况下编写的查询仍然可以使用它:
执行计划显示正在访问的索引视图:
对于其他版本,您需要直接引用视图,并使用
NOEXPAND
提示:执行计划:
与索引计算列相同的连接设置限制适用于索引视图。即使在企业版中,您也可以选择使用该
NOEXPAND
版本,因为视图的使用是有保证的(不是由优化器决定的),并且基数估计通常也会更好。添加索引视图的效果取决于很多因素,因此您需要对其进行测试。任何安全的解决方案都有可能增加争用,但在索引计算列不适合的情况下,索引视图通常是下一个最佳选择。如果做得好,效果可能很小。单个表上的索引视图的开销不会超过向基表添加新的非聚集索引的开销。
我考虑过添加这样的计算列:
但这不起作用。
这有点麻烦,但它有效:
但您需要在表上添加触发器以保持
diff
列更新。添加约束也很好:
...您如何选择维护列(触发或更改表上的所有插入/更新过程)。