There is a table holding some values like:
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
In order to select the longest prefix of a given text and return the name I use the following SQL:
select top 1 name from prefixes where :text like prefix + '%' order by prefix desc
And this is exactly what I need, when I give text record1 it returns me name for record 2 when record1 it returns me name for record 1, if I give a it returns me name for record 4.
But the problem is that this is executed a few times and the table is updated a lot, so the performance in my case (table with just 210000 rows) is around 300ms, I would like to reduce this, is there something could be improved on the query or even on the database?
I don’t know Sybase internals really well. However, look at the plan to see if it is using the index. If so, is it doing a full scan of the index or is the engine smart enough to understand the “like”.
My guess is that the engine is doing a full scan. You might be able to trick it to seeking to the right starting location by changing the query:
However, it will probably do a full scan from that point forward. You can fix this by having a maximum place to search:
(Assuming that you are using alpha-numeric values in the prefix, this should be ok. You can also use something like :text + ‘}’, because ‘}’ has a very high ASCII value, assuming you are using an ASCII collating sequence.)
Are your prefixes known in advance? That is, for “record1” is the prefix always “record”? Or are you considering “r”, “re”, and so on.
If the former, then add a new column which contains the “base” part of the prefix. Build an index on this column and change the join to equality. The engine will fetch only the records from the index.
The issue of having the column “name” in the index is to prevent the additional step of looking up the name on the data pages for the table. Once again, this depends on how Sybase optimizes the query. It should find the appropriate records only using the index and then look up the fields after applying the
top 1. However, if it fetches all the values, then applies thetop 1, having “name” in the index will be a benefit.