Reducing the time to populate ListBox Controls from database

Posted on 2004-09-30
Last Modified: 2010-04-16

We have a Delphi 6 application that displays a DataGrid and a ListBox that are populated from a table of an SQL Server 2000 database. The DB table contains 1,55,567 rows and it takes about 4 secs to retrieve all rows from the DB.

Now, when we try to loop thru the recordset to populate the ListBox and DataGrid, it takes almost 3 minutes to get the data into the ListBox. I would like to know if there is an apporach using which this delay can be minimised as this is a client server application and the users get anxious about the delay that occurs in populating these controls.

Any help would be appreciated.
Question by:ashish_me2

Expert Comment

ID: 12188465
Have you tried Datasets DisableControls, before starting to populate and EnableControls after populate?

Author Comment

ID: 12188471
No, can you please explain about what this does.

Accepted Solution

jpedef earned 43 total points
ID: 12188578
I am assuming here that you populate Listbox programmatically.
If you loop through a large number of records you should always call DisableControls to prevent dataset for trying to update datacontrols. In my experience it should be called even if there are no datacontrols linked to a dataset.
Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.


Assisted Solution

pritaeas earned 41 total points
ID: 12188692
What I do in these situations is the following: Populate a stringlist first with the items you want in the listbox. Then set the BeginUpdate property. I'm not sure of the top of my head if it is a property of tlistbox, or of the items. Then assign the stringlist to the items. Set EndUpdate to mark for completion. The BeginUpdate will block visual updates until you set EndUpdate. This will save a lot of time.
LVL 17

Assisted Solution

by:Wim ten Brink
Wim ten Brink earned 41 total points
ID: 12188710
Make the listbox virtual. Make the grid virtual. Or use data-aware listboxes and grids...

Making these components virtual basically means that you just tell them how much items there must be in the grid or listbox, but you don't assign the values yet. You just use the customdraw events to check which item needs to be drawn, then look it up in your recordset and then just draw it in it's place. Don't fill your grid or listbox with real data since that would be a huge waste of memory if you have this many items.

Also, keep in mind that no sane user would ever want to see this much records on his screen. It is insanity by itself to show a user this much data since he can't do anything with it. It's like when you go to the grocery store to buy a banana and the shopkeeper tells you to go find it in this huge truck full fruits.
Lesson number one of good GUI design: NEVER show the user an enormous list of data. Offer them filters and just return e.g. the top-250 records. (And warn them if their filter resulted in more than 250 items in that case.) Or do like Google does... Get all the data and offer it to the user as multiple pages, with about 25 items per page. If the user goes to the next page, just fill the grid and listbox with the next 25 records.
But displaying hundreds of thousands of records to the user is plain stupid.

Expert Comment

ID: 12193350
It could be that I'm not quite getting it, but I don't think splitting information into pages is better then showing them as a whole. It still will be a lot of information. I'm with pritaeas here. if you really want to split those rows into multiple pages, a stringlist is quicker than a recordset.
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12193832
In general, you should just limit the amount of data that you show to the user to something around 100 to 250 records. More than 100 is already quite a large amount, though. If there's more data to show than this, you have several options:

*) Show just a summary, grouping data and calculating totals.
*) Divide the data in multiple pages and allow users to jump to a specific page.
*) Provide the user a way to filter the data so the output is limited to what the user wants to see.

For example, say that you keep track of every phonecall made in your company. Your company has 5000 employees and half of them work for the helpdesk or are salespersons. You could imagine that this would be a lot of phonecalls. Now, after a year, you want an overview. How would you like to see it?
Would you like to see every phonecall in a grid? Let's hope not. Users are more interested in calculated results. E.g. a sum of call lengths per employee. Or the total number of calls per week. Maybe just an overview of all calls of Mr. X on date MM-DD-YYYY.

Expert Comment

ID: 12194979
Comment only

Am I missing something here...


'The DB table contains 1,55,567 rows and it takes about 4 secs to retrieve all rows from the DB.

Now, when we try to loop thru the recordset to populate the ListBox and takes almost 3 minutes to get the data into the ListBox'

Why are you then putting them into another grid (if this is what you are doing)...

If you need to format them or add extra unbound columns - you should be using a datagrid and populating using unbound events...

Data grids call batches of items which is easy when you think about it (using Top and Bottom predicates).

I can't see a scenario where you would be putting very large numbers of items into a listbox as being realistic in interface terms.

Who could possibly make choices out of millions of items - it makes no sense to me - please explain further.


LVL 11

Expert Comment

ID: 12197372
As already stated a listbox is not suited very well for the job.
It needs to hold *all* rows even while displaying only a small amout of entries.
Using a control to handle a virtual list is the way to go.
Such a control stores only the displayed values. Mike Lischke's TVirtualTreeView is the most renowned control of that sort.

Featured Post

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question