如何通过选择表中最长的前缀来提高性能

时间:2012-12-01 11:59:58

标签: sql sybase

有一个表格包含一些值,如:

id  | prefix         | name 
----+----------------+--------------------------
1   | record1        | name for record 1
2   | record2        | name for record 2
3   | record         | name for record 3
4   | another rec    | name for record 4

为了选择给定文本的最长前缀并返回名称,我使用以下SQL:

select top 1 name from prefixes where :text like prefix + '%' order by prefix desc

这正是我所需要的,当我提供文字record1时,如果我name for record 2 record1,它会返回name for record 1 {}返回给我a它返回给我name for record 4

但问题是这个执行了几次并且表格更新了很多,所以我的情况下的性能(表只有210000行)大约是300ms,我想减少这个,有什么可以在查询甚至数据库上进行改进?

1 个答案:

答案 0 :(得分:1)

我不知道Sybase内部真的很好。但是,请查看计划是否正在使用索引。如果是这样,它是否正在对索引进行全面扫描,或者引擎足够智能以理解“喜欢”。

我的猜测是引擎正在进行全面扫描。您可以通过更改查询来欺骗它寻找正确的起始位置:

where prefix >= :text and :text like prefix + '%'

然而,从那时起,它可能会进行全面扫描。你可以通过最大限度的搜索来解决这个问题:

where prefix >= :text and prefix <= :text + 'zzz'

(假设您在前缀中使用字母数字值,这应该没问题。您还可以使用类似:text +'}'的内容,因为'}'具有非常高的ASCII值,假设您正在使用ASCII整理顺序。)

您的前缀是否已提前知晓?也就是说,对于“record1”来说,前缀总是“记录”?或者你在考虑“r”,“re”等等。

如果是前者,则添加一个新列,其中包含前缀的“base”部分。在此列上构建索引并将连接更改为相等。引擎只会从索引中获取记录。

在索引中使用“name”列的问题是为了防止在表的数据页面上查找名称的附加步骤。再一次,这取决于Sybase如何优化查询。 仅使用索引查找相应的记录,然后在应用top 1后查找字段。但是,如果它获取所有值,则应用top 1,在索引中具有“name”将是一个好处。