繁体   English   中英

索引扫描而不是搜索

[英]Index scan instead of a Seek

我在表上添加了一个新的计算列:

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是计算列。

因为索引没有覆盖,并且估计索引返回的行数

  WHERE DATAORA_STOCK >= @Data1

将导致太多的查询来检索丢失的列值,以至于扫描整个对象就便宜了。

如果估计错误,则可以尝试使用OPTION (RECOMPILE)使其嗅探@Data1的值(如果估计仍然错误,请更新该列上的统计信息)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM