The expense of getFoundSetCount()

I’m considering adding in a user advisory very common in FMP – “you’re currently on record 3 of 7”. Is this feature practical in Servoy?

The function databaseManager.getFoundSetCount(foundset) has an advisory this is an expensive function. Is there a way of shortcutting a precise calculation if the current count rises beyond 200 and returning something like “200+”? Also, is it still expensive if there’s a low count of records in the current foundset?

Normally a database starts providing rows for a query when the fetch buffer is full, for select count(*)… as used getFoundSetCount(…)/getTableCount(…) it can return when processed all records.
In normal use this means you will notice a delay when having more than ~100K records in your table.

Jan Blok:
Normally a database starts providing rows for a query when the fetch buffer is full, for select count(*)… as used getFoundSetCount(…)/getTableCount(…) it can return when processed all records.
In normal use this means you will notice a delay when having more than ~100K records in your table.

What’s the difference between databaseManager.getFoundSetCount(foundset) and controller.getMaxRecordIndex()? Correct me if I’m wrong. Superficially, they appear to do the same thing. When should one be used instead of the other?

no they aren’t doing the same thing

controller.getMaxRecordIndex() is returning the numbers of rows we currently have knowlegde of in servoy (the rows that are in mem of the client). It will for example only return 200 the first time you call it directly after a foundset is loaded (if you didn’t scroll or set a selected index somewhere)

The getFoundsetCount() gives the real total what is in the database. The number of rows the foundset whould eventually have in mem when you scroll completely to the last record.

use controller.getMaxRecordIndex() as much as you can. And only use the other if you really,really need the complete count..

But I believe it is not very expensive if you do a straight databaseManager query ('select count(*), etc.) and return that result to your form if you need to get what the ‘actual’ number of records in your selection is. I have certainly found that to be the case so far anyway.

Here’s my problem, two problems actually. I want to give my user an accurate count of how many clients he has. I sense databaseManager.getFoundsetCount() will serve that purpose until my user’s client base exceeds 100,000.

The other problem is I want to give my user a table showing currently browsed records – presumably the 200 or so brought into the buffer. However I’m still playing around with just a handful of sample records. I don’t yet know what will happen when the potential count rises to several thousand.

It’s my untested supposition that on first opening my table of “all records” will simply show the first 200. That when they jump to the last record they will still be able to click the Next button to pull up another record into the buffer. That in practice they’ll use the query routines to bring in the records they really want to focus on. No one needs to scroll through 10,000 records although psychologically they need to know they’re there.

Am I on the right track with the above? Insights gratefully received.

If you need it, use it…
However you could make the code for retrieving the count optional… like the following pseudocode:

if (globals.showFoundSetCounts == 1)
{
<doCountRetrieval and show>
}
else
{
<show in count display it is disabled>
}

In case you ever whould get performance problems, you could turn it of by setting the global to zero

Here’s how we do it in our solution:

Whenever the foundset changes (on a find or other action that loads records), a method calls controller.getMaxRecordIndex() and places this value in a global for display. If controller.getMaxRecordIndex() is a multiple of 200, then the method calls getFoundSetCount() and places that in the display global instead. This way the display global always contains the correct maximum record count, but getFoundSetCount is only is called when a query returns more than the 200 record buffer.

We haven’t noticed much of a performance hit in our application doing things this way.

Excellent. Exactly the help I was looking for. Thanks.

One thing I am curious is hat kind of ‘maximums’ might you come up with in your solution? thousands? tens of thousands? hundreds of thousands? i.e. how big is the underlying table.
Thanks,

John

john.allen:
One thing I am curious is hat kind of ‘maximums’ might you come up with in your solution? thousands? tens of thousands? hundreds of thousands? i.e. how big is the underlying table.
Thanks,

John

Current clients have tens of thousands. But I don’t want to paint ourselves into a corner by assuming an upper limit.

Current clients have tens of thousands. But I don’t want to paint ourselves into a corner by assuming an upper limit.

Actually I was wondering what dponti’s solution had for numbers and his experience with using those count functions, i.e. how large the table is.

The main table where we search from currently has about 8100 records. Typical searches produce from one record to the entire table’s worth of records. The controller form shows two global fields - one that displays the current record index and the other that displays the number of records in the current foundset (calculated as I described above). Both global fields are recalculated on an onRecordSelect event - since the solution allows both Servoy-managed searches (using Find mode) and scripted finds. If you controlled the solution through scripted finds only, then the max record only need be calculated whenever a search is conducted (eg whenever the foundset changes).

With these numbers we haven’t noticed any significant performance hits. The global fields recalculate rapidly - when getFoundSetCount must be called, there may be a delay of a second or so before the new foundset displays, otherwise it’s nearly instantaneous.

if I don’t load the full foundset then the summary fields will show correctly or only when the foundset is loaded completely?

I think the summary field is just ok. I have just tested it. It show correctly even only 200 records are loaded

Thanks