QuoteReplyTopic: Any idea about speeding up the load time of a form? Posted: 09-Jan-2009 at 12:04pm
In my application, I have noticed that certain forms take quite awhile to display the first time during an application session, but then act responsively when the same form is requested later in the session. Of course, after the application is shut down and re-opened, it again takes a very long time to display the form.
For instance, I have a "Transactions" Form, which takes an unimaginably long time to display (nearly 10 minutes), and when I check the debuglog, it lists 2000 lines of database queries:
RdbKey: [default] Sql: select * from "dbo"."FinancialTransaction" RdbKey: [default] Sql: select * from "dbo"."TransactionLineItem" where ((1 = 0)) RdbKey: [default] Sql: select * from "dbo"."TransactionLineItem" where ("dbo"."TransactionLineItem"."TransactionREF" in (?)) Params: v0=00165662-a9be-4900-84eb-3b2ee391349e RdbKey: [default] Sql: select * from "dbo"."EventTicketSale" where ((1 = 0)) RdbKey: [default] Sql: select * from "dbo"."EventTicketSale" where ("dbo"."EventTicketSale"."TransactionLineItemREF" in (?)) Params: v0=56e4a6d4-a73f-4a1d-8eb8-459b098f6877 RdbKey: [default] Sql: select * from "dbo"."Payment" where ((1 = 0)) RdbKey: [default] Sql: select * from "dbo"."Payment" where ("dbo"."Payment"."TransactionREF" in (?)) Params: v0=00165662-a9be-4900-84eb-3b2ee391349e RdbKey: [default] Sql: select * from "dbo"."HouseholdBusiness" where ((1 = 0)) RdbKey: [default] Sql: select * from "dbo"."HouseholdBusiness" where ("dbo"."HouseholdBusiness"."HouseholdBusinessGUID"=?) Params: v0=dfecf0d1-84f8-470a-97d6-e1c6ae121c07 RdbKey: [default] Sql: select * from "dbo"."TransactionLineItem" where ("dbo"."TransactionLineItem"."TransactionREF" in (?)) Params: v0=8253ad0f-a3a0-44a3-ae56-7214fd358cfb RdbKey: [default] Sql: select * from "dbo"."TransactionLineItem" where ("dbo"."TransactionLineItem"."TransactionREF" in (?)) Params: v0=ffa1380b-c33f-46ea-8d28-4a528865e113 RdbKey: [default] Sql: select * from "dbo"."HouseholdBusiness" where ("dbo"."HouseholdBusiness"."HouseholdBusinessGUID"=?) Params: v0=48f53d40-1eff-4a5f-9788-18e9246dc5f9 RdbKey: [default] Sql: select * from "dbo"."TransactionLineItem" where ("dbo"."TransactionLineItem"."TransactionREF" in (?)) Params: v0=0018c8c4-b615-4c6e-9120-167fd8dc369c RdbKey: [default] Sql: select * from "dbo"."HouseholdBusiness" where ("dbo"."HouseholdBusiness"."HouseholdBusinessGUID"=?) Params: v0=bcddfc9d-6fc1-4a62-a72c-ca92f7e85219
Does anyone have any insight into this? Specifically, I would love to know if there is some way I can speed up the form display and possible "pre-load" the form (on a different thread) when the application starts, so when the user requests the form, it displays quickly.
Right now I have this code running in the Shell application (on app start): (entityTypes is a list of a few of the entity types in my application which seem to be the slow-loading form entities)
/// <summary>Get all Entities of Types in a list into the PM asynchronously</summary> /// <param name="entityType">The list of Types to get entities of</param> public static void GetDataAsync(IEnumerable<Type> entityTypes) { string TypeName; string Token;
foreach (Type type in entityTypes) { TypeName = type.Name; Token = TypeName + "_Complete";
Just getting the data asynchronously may not help very much if your first asynchronous request gets a lot of data from the database (or too little data). Try to get enough data on your first request so that you can make an initial display of the form, then in your background thread, you can ask for more data.
I would also consider using paged queries, and a paged form.
Thanks for the ideas, David. I am investigating the "paged queries".
How I have it set up now is that on application open, I have async queries running that pull data from all the tables into the cache. The user interface of the application appears in a reasonable amount of time for "application boot" (the initial "home" screen doesn't contain any data for display), but when the user then clicks to one of the main forms (which holds all the people and addresses, etc. in the database (11K records), it takes a very long time to load, or seems to hang completely.
The user might want to look up any person in the system, so I'm not sure about how paging would work (they use a lookup combo box to select a person to "jump" to, generally, though the form also has a DataNavigator control).
//Main Lists // Query orders in ascending HBName sequence. RdbQuery aQuery = new RdbQuery(typeof(HouseholdBusiness)); aQuery.AddOrderBy(HouseholdBusiness.HBNameEntityColumn, ListSortDirection.Ascending);
// Build a paged query to retrieve 10 items at a time. PagedRdbQuery pagedQuery = new PagedRdbQuery(aQuery); pagedQuery.PageSize = 10;
// Specify whether the last item of the page will be first item on next page. pagedQuery.PagesShouldOverlap = false;
while (true) { mListMainEntity.ReplaceRange(mPersMgr.GetEntities<HouseholdBusiness>(pagedQuery)); DebugFns.WriteLine("Current page = " + pagedQuery.CurrentPage.ToString()); DebugFns.WriteLine("Count for this page = " + mListMainEntity.Count.ToString());
if (pagedQuery.IsLastPage) break;
// Advance the query. pagedQuery.NextPage(); } ...
but it took just as long (or possibly longer...) with no quicker form display, and once the form DID display - it was totally empty of data. I must be missing something very basic here...
I also was experiementing with running the query async...
I don't mind if the records take some time to load into the system, but I'd really like to have the form display with SOMETHING as soon as possible, and still have all the data loading in for access.
If someone could point out how I am not understanding this, or provide some code samples I would be grateful.
Continue to work on thr paging example. I am sire that you will eventually "get it".
Also, work through the Asynch Query examples in the Tutorials until you understand why this helps performance.
Maybe, your problem is that you just have too much data. Is there any way to make the amount of data smaller. For example, can you have your user choose (to begin with) "This Year's Customers" and "Last Year's Customers", or "Customers from New York" and "Customers from New Jersey". Look at some examples of our QBE Control where an initial control narrows the number of items that will be included.
You say that "The user might want to look up any person in the system, so I'm not sure about how paging would work".
You have a choice. You can try to display a list of all the customers and then have your user "page" or "scroll" that list, or you can start with a "search" function (or both). If you don't have to build a large list and can just "search", that is the fastest, but probably, you want your user to be able to page though a large list.
Another advanced techniaue you might consider is to use a "Dynamic Entity". For example, get just the First Name and Last Name of each customer, and construct a Dynamic Entity that just has these two columns. and so you would just be retrieving two columns of each row. That would make the retrieval from the database faster. Display a list of these Dynamic Entities. When the user clicks on the Customer, you could retrieve the record with all columns.
Believe it or not, I am still working on improving the load time of my forms.
I have been able to make some progress - I added a quick "Search" box to the top of the form, so the underlying data is not loaded until the user types in part of a name to search on. After clicking a "Get Records" button, an RDB query retrieves only the few records which match that search term, then the user can click through that smaller result-set. This is working pretty well, and the record retrieval is fairly quick.
However, I noticed that some of the combo boxes on my form still require a large number of records to be retrieved. For instance, I have an Entity called "Household" and that is related to an entity called "Person" in a 1-many relationship. If I am on the "people" form, there is a combo box indicating which Household that person belongs to. The box needs to have a list of all the available households, and should be displaying the current linked household name in the combo box on the form.
I found that as long as I am calling the database to fill a list for that combo-box, the load time of the form is still very long. On Form_Load I have it pull in the lookup list data:
Since the Household lookup list only needs a few columns - the GUID and some display properties, I thought I would create a separate entity type which would only get those few necessary columns to be used as the source of the look-up list, and load those instead:
Which does somewhat reduce the load time, but the combo-box on the form does not display the currently linked Household. I shows as blank, witht he ability to select from the "HouseholdBusiness_Lookup" list.
Perhaps it is treating the relationship between "Person" and "HouseholdBusiness_Lookup" as different from the relationship between "Person" and "HouseholdBusiness" because they are different entities - even though the same database relationship is used to define them?
Am I going about this wrong - or will I need to load int he regular "HouseholdBusiness" entity to fill the look-up list?
Try displaying the HouseholdBusiness_Lookup relation property of the Person in the ComboBox, instead of the
Household. Then, in a custom setter for HouseholdBusiness_Lookup, also set the Household.
I actually decided that the overhead to load in all the possible objects (even if they were "smaller") was still too much, so I am removing the drop-down from the main form and instead having a button to "Change..." which will bring up a pop-up form to choose the new Household. This will limit the data loading to happen only when requested by the user (which, in reality, won't be that often).
There are really only 2 entities which are this unwieldy, so implementing the dialog box shouldn't be too onerous.
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot delete your posts in this forum You cannot edit your posts in this forum You cannot create polls in this forum You cannot vote in polls in this forum