I have a simple table based queue system. In its simplest form, it consist of an id, a queue name, and a status. When reading the next message from a given queue, we need to ensure FIFO (first in first out), i.e. the lowest id from the given queue with the given status. This all works fine with some thousand rows, but when we reach 1M+ rows it does not go well anymore.
We can’t use rownum = 1 as this is done prior to sorting, the sorting is done based on the id column solely (asc). If I make a cursor and sort by id 1000 times this takes around 100ms all together which is a good performance (0.1 ms / loop). If I include the status and queue name in the query (which I need, as I need the lowest id of an unread message for a specific queue) it takes around 1300ms for 10 loops (130ms / loop), which is far from ok.
I have tried having an index on each of the three columns, also a combined index on id, queue, status and finally a combination with an index on id, and a combined index on queue and status. The id column is also the primary key. All combination has been tried in a rule based setup also (using the rule hint).
Best regards,
Michael Ringholm Sundgaard – iHedge A/S
http://www.ihedge.dk http://www.ibrain.dk
One thing that I didn’t see mentioned in the indexes which you tried would be an index on (queue, status, id). If you put the id at the start of your index it mostly destroys the use of the index since you’re looking for the “lowest one”, which is meaningless until the other criteria is applied.
The ordering of the columns in an index can often be just as important as the actual columns themselves.