我正在使用SQL Server 2008,它拒绝对我的索引执行搜索,该索引覆盖计算列.
我的表看起来像这样:
CREATE TABLE Person
{
Id uniqueidentifier NOT NULL,
InsertDate datetime NOT NULL,
PhoneNumber NULL,
PhoneNumberComparable AS (MakePhoneNumberComparable(PhoneNumber)) PERSISTED,
... etc...
}
Run Code Online (Sandbox Code Playgroud)
ID列上有一个聚簇主键索引,还有InsertDate列上的索引.
PhoneNumberComparable计算列上有一个索引,如下所示:
CREATE NONCLUSTERED INDEX IX_Person_PhoneNumberComparable ON Person
(
PhoneNumberComparable ASC
)
Run Code Online (Sandbox Code Playgroud)
索引都具有最新的统计信息.
我的查询如下所示:
SELECT TOP 20 * FROM Person
WHERE PhoneNumberComparable = @PhoneNumber
ORDER BY InsertDate DESC
Run Code Online (Sandbox Code Playgroud)
默认情况下,SQL Server决定使用InsertDate上的索引而不是PhoneNumberComparable上的索引,从而导致性能非常差.
如果我尝试强制使用电话号码索引,通过向查询添加WITH(INDEX = IX_Person_PhoneNumberComparable),SQL将执行扫描而不是搜索.
如果我尝试使用FORCESEEK查询提示,那么SQL Server会给我以下错误:
由于此查询中定义的提示,查询处理器无法生成查询计划.重新提交查询而不指定任何提示,也不使用SET FORCEPLAN.
所以基本上,由于某种原因,SQL Server拒绝寻求我的索引!为什么?
编辑
根据评论中的建议,我简化了查询,但问题仍然存在(执行主键扫描而不是搜索电话号码索引):
SELECT TOP 20 PhoneNumberComparable FROM Person
WHERE PhoneNumberComparable = @PhoneNumber
Run Code Online (Sandbox Code Playgroud)
我相信我已经弄明白了.
问题是由于MakePhoneNumberComparable函数使用了另一个模式下的另一个函数.要解决这个问题,我必须克隆另一个函数的第二个副本,但是在与表相同的模式下移动它.
本文(感谢评论者Kahn)说,如果"计算列中的所有函数引用与表具有相同的所有者",则只能定义索引.
好吧,这个所有权要求不仅非常令人讨厌,而且微软的文档至少可以说是非常令人困惑的:
| 归档时间: |
|
| 查看次数: |
3499 次 |
| 最近记录: |