0

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

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 2record1返回我name for record 1,如果我给出a它返回我name for record 4

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

4

1 回答 1

1

我不太了解 Sybase 内部结构。但是,请查看计划以查看它是否正在使用索引。如果是这样,它是对索引进行全面扫描还是引擎足够聪明以理解“喜欢”。

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

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

但是,它可能会从那时起进行全面扫描。您可以通过设置最大搜索位置来解决此问题:

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

(假设您在前缀中使用字母数字值,这应该没问题。您也可以使用 :text + '}' 之类的东西,因为 '}' 具有非常高的 ASCII 值,假设您使用的是 ASCII 整理序列。)

你的前缀是事先知道的吗?也就是说,对于“record1”,前缀总是“record”吗?或者您是否正在考虑“r”、“re”等。

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

在索引中包含“名称”列的问题是防止在表的数据页上查找名称的额外步骤。同样,这取决于 Sybase 如何优化查询。它应该只使用索引找到适当的记录,然后在应用top 1. 但是,如果它获取所有值,则应用top 1,在索引中具有“名称”将是一个好处。

于 2012-12-01T17:43:12.810 回答