有一个表格包含一些值,如:
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,我想减少这个,有什么可以在查询甚至数据库上进行改进?
答案 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”将是一个好处。