Like运算符,Hashed与Non-Hashed的最佳SQL In-Memory OLTP索引类型

时间:2014-06-05 06:05:45

标签: sql indexing

我正在考虑在具有500多万条记录的桌子上进行内存中OLTP实现

我使用以下查询,它运行大约5毫秒,但是如果我能获得更好的性能会很好

  SELECT TOP 1 ClassId 
    FROM Exchanges 
    where ExchangeSetId = 1 
       and BasePrefix like left(@BaseNumber, 3) + '%' 
       and @BaseNumber like BasePrefix +'%' 
       and @DestNumber like DestPrefix +'%'

上述查询是从我提出的背景问题

中获得的

SQL Server Performance tips for like %

ExchangeSetId,BasePrefix,DestNumber上目前有索引可以提高性能,调整顾问建议使用以下索引,脚本如下

USE [JCE]
GO

/****** Object:  Index [ExchangeIdx]    Script Date: 5/06/2014 3:55:35 PM ******/
CREATE NONCLUSTERED INDEX [ExchangeIdx] ON [dbo].[Exchanges]
(
    [ExchangeSetId] ASC,
    [BasePrefix] ASC,
    [DestPrefix] 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)
GO

但是我对在优化迁移顾问中使用的索引方法感到困惑,提供了屏幕截图

enter image description here

问题,在这种情况下即使使用OLTP也值得吗?

如果是这样,那么在上面的查询中显示的like运算符最适合的索引类型是什么?

修改

我的直觉告诉我它应该是非散列索引,但我不知道SQL的内部足以证明它

1 个答案:

答案 0 :(得分:1)

当我无法通过思考实验或应用知识证明某事时,我会做一件事,我测量。

但是为了回答:

我假设您的ExchangeSetId是基数非常低的字段。

我的直觉是,即使你只需要在结果中返回1个记录,使用TOP 1,你仍然使用2个范围谓词到达那里,所以我避免使用HASH索引并且还避免使用最低基数字段作为指数的领先领域。尝试使用常规的NONCLUSTERED索引或CLUSTERED索引,保留索引顺序前面的范围谓词(BasePrefix和DestPrefix)中的2个字段。

无论如何,5毫秒的查询性能并不差,所以你需要决定如何衡量成功。您需要创建一个基线:一个理想的测试用例,实际上有500万条相似的记录,除了3个关键字段组成一个UNIQUE索引,并在没有通配符的情况下查询它,得到一行,并测量该案例的返回速度数据库中的记录(使用内存中的OLTP选项以及这些索引类型中的一个或两个)。衡量一下。这代表了每个人都能做到的最好。如果结果低于1毫秒,那么你的转身锻炼可能是值得的,但如果没有,那么可能没有你想要的延迟增益那么多,然后你需要决定是否通过延迟测量成功唯一重要的是,或者你应该测量增加的并发性(这是OLTP在内存中的另一个好处选项)。在那之后,如果你不需要增加并发性,那么也许根本不需要。