我在桌面上添加了一个新的计算列:
ALTER TABLE MyTable
ADD DATAORA_STOCK AS (Data_stock + Ora_Stock)
Data_Stock
类型为char(8)
且Ora_Stock
类型为char(6)
。
在此DATAORA_STOCK
列中创建新的非聚集索引之后:
CREATE NONCLUSTERED INDEX [IX_MyTable_DATAORA_STOCK] ON MyTable
(
[DATAORA_STOCK] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
当我执行这两个查询时:
SELECT * FROM MyTable
WHERE DATAORA_STOCK = @Data1
和
SELECT * FROM MyTable
WHERE DATAORA_STOCK >= @Data1
我有两个不同的执行计划。首先查询IX_MyTable_DATAORA_STOCK并进行密钥查找。
为什么第二次在聚簇索引上执行扫描索引?
使用OPTION(RECOMPILE)
它运作良好,实际(未估计)执行计划是正确的。
不幸的是我无法修改查询文本,因为它是从应用程序中调用的...
我已经更新了我桌上的统计数据,但没有任何变化
确切的查询文本是:
SELECT *
FROM MyView
WHERE DatAgg+OraAgg >= @Data1 AND DatAgg+OraAgg <= @Data2
原始表格中DatAgg+OraAgg
为DATAORA_STOCK
(视图只是MyTable的投影),而DATAORA_STOCK
是计算列。
答案 0 :(得分:2)
因为索引不覆盖,并且它估计
返回的行数 WHERE DATAORA_STOCK >= @Data1
将导致如此多的查找以检索丢失的列值,以便扫描整个内容更便宜。
如果估算错误,您可以尝试使用OPTION (RECOMPILE)
来嗅探@Data1
的值(如果估算仍然错误,请更新该列的统计信息)