I have a Silverlight app that makes multiple (often concurrent) asynchronous calls to an Oracle database. The largest database table stores around 5 million records. Below is a summary of how the Silverlight app works, followed by my question.
-
The user sets query criteria to select a particular group of records, usually 500 to 5000 records in a group.
-
An asynchronous WCF call is made to the database to retrieve the values in four fields (latitude, longitude, heading, and time offset) over the selected group of records (meaning the call returns anywhere from 2k to 20k floating point numbers. These values are used to plot points on a map in the browser.
-
From here, the user can choose to graph the values in one or more of an additional twenty or so fields associated with the initial group of records. The user clicks on a field name, and another async WCF call is made to retrieve the field values.
My question is this: does it make sense in this case to store the records selected in step one in a temp table (or materialized view) in order to speed up and simplify the data access in step three?
If so, can anyone give me a hint regarding a good way to maintain the browser-to-temp-table link for a user’s session?
Right now, I am just re-querying the 5 million points each time the user selects a new field to graph–which works until the user selects three or more fields at once. This causes the async calls to timeout before they can return.
We can do this using a CONTEXT. This is a namespace in session memory which we can use to store values. Oracle comes with a default namespace, ‘USERENV’, but we can define our own. The context has to be created by a user with the CREATE ANY CONTEXT privilege; this is usually a DBA. The statement references a PACKAGE which sets and gets values in the namespace, but this package does not have to exist in order for the statement to succeed:
Now let’s create the package:
There are three methods, to set, get and unset a value in the namespace. Note that we can use one namespace to hold different valiables. I am just using this package to set one variable (USER_ID) in the USER_CTX namespace.
So, how does this solve anything? Here is a table for the temporary storage of data. I’m going to add a column which will hold a token to identify the user. When we populate the table the value for this column will be provided by
CTX_PKG.GET_USER_ID():… and over that table I create a view:…
Now, when I want to store some data in the table I need to set the context with a value with uniquely identifies my user.
This statement populates the temporary table with twenty random rows:
I can retrieve those rows by querying the view. But when I change my USER_ID and run the same query I cannot see them any more:
So, the challenges are:
Also, remember to clear out the table once the user has finished with it.