Hy guys,
我继承了一个包含下表的数据库,只有200行:
CREATE TABLE [MyTable](
[Id] [uniqueidentifier] NOT NULL,
[Name] [varchar](255) NULL,
[Value] [varchar](8000) NULL,
[EffectiveStartDate] [datetime] NULL,
[EffectiveEndDate] [datetime] NULL,
[Description] [varchar](2000) NOT NULL DEFAULT (''),
CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
正如您所看到的,UniqueIdentifier列上有一个Clustered PK。我正在做一些性能检查,到目前为止最昂贵的查询(CPU和IO)如下:
SELECT @Result = Value
FROM MyTable
WHERE @EffectiveDate BETWEEN EffectiveStartDate AND EffectiveEndDate
AND Name=@VariableName
上面的查询封装在UDF中,通常在选择列表或where子句中不调用udf,而是返回通常分配给变量。
执行计划显示聚集索引扫描
我们的系统基于大量聚合和数学处理实时处理。每次我们的Web应用程序刷新主页面时,它都会调用一堆存储过程和UDF,上面的查询每个用户每次刷新运行大约500次。
我的问题是:我应该将PK更改为非聚集并在如此小的表中的Name,EffectiveStartDate,EffectiveEndDate上创建聚簇索引吗?
答案 0 :(得分:1)
不,你不应该。您可以添加另一个将覆盖索引的索引:
CREATE INDEX [IDX_Covering] ON dbo.MyTable(Name, EffectiveStartDate, EffectiveEndDate)
INCLUDE(Value)
如果@VariableName
和@EffectiveDate
是具有正确类型的变量,您现在应该看到索引搜索。
我不确定这会有所帮助,但你需要尝试,因为200行的索引扫描不算什么,但调用它500次可能是个问题。顺便说一句,如果这200行在一个页面中,我怀疑这将无济于事。问题可能出在其他地方,例如打开连接500次或类似的事情......