Wednesday, January 13, 2010

MapViewer performance tuning tips - Part 1

This is the first of a series of blogs on MapViewer performance tuning.


When your MapViewer application performs poorly, there are many possible causes. Maybe your application is trying to (unnecessarily) display way too many features on a map or layer. Maybe your database query (for dynamic themes) is too complicated and poorly optimized. Or maybe the database is doing too many disk I/Os when fetching the result set for a theme. It could also be due to a poorly configured MapViewer in-memory cache, an overwhelmed J2EE container (overloaded with many other applications), or just a very slow middle-tier box. It could be all of the above. The symptom however is always the same: when a user clicks on the map to pan or zoom, she will wait a long time before the map completely refreshes itself.

So how to find the true bottleneck? Where do you start when diagnosing a slow mapping application? The short answer, is to first identify the most time consuming theme(s) in your application, by looking at the log file.

To do so set MapViewer's logging to the "finest" level, restart MapViewer, and run the application just long enough (or manually submit a single XML map request) to generate some meaningful logs. When scanning the freshly created MapViewer log file, for each theme you should see several log records like the following:

FINER: [ THEME_DEMO_HIGHWAYS ] sql exec time: 585ms, total time loading 8 features: 2679ms.
FINER: time to render theme THEME_DEMO_HIGHWAYS with 8 styled features: 72ms
FINER: time to label theme THEME_DEMO_HIGHWAYS with 8 styled features: 112ms

In the first log record, pay special attention to the last number, 2679ms. This number (in milliseconds) indicates how long it took the database to execute the theme query, fetch result rows from data blocks, and transmit the result set over the network to MapViewer. For simplicity we will call this the "database time". Likewise let's call the combined rendering and labeling time indicated by the second and third log records the "MapViewer time"; after all that is how long MapViewer actually spent doing something useful instead of just waiting for and receiving data from the database.

In many cases, the database time will be the dominant one, so you will need to poke around the database and speed things up there. We will get into it later.

If the MapViewer time is high, we will need to find out why. One recommended approach is to run a CPU profiling of the MapViewer instance. Again we will provide more details in a later post.

Reducing these two types of time will have a positive impact on your application's performance regardless of which MapViewer API you are using.

Note that starting with MapViewer 11g R1 there is another way to easily spot themes with excessive "database time". To do so you must first log in as the MapViewer
admin user. Then manually open the /mapviewer/admin.html page in your browser. You will see a "Top theme queries" text area with a Submit button underneath it. Click on the submit button to see a list of top (database) time-consuming queries. It's a good idea to first click the "Reset top theme queries" button so that MapViewer clears any existing list of themes and starts gathering fresh stats for you.

Sometimes you may find that all of your themes are loaded and rendered quickly, but your application still takes a long time to display the map. Let's simply call this the "user time", since it is the time a user spent staring at a spinning clock or progress bar. When the sum of the "database time" and "MapViewer time" accounts for only a small portion of the "user time", we suggest you use a FireFox addon called "FireBug" to find out what exactly is happening on the wire and in your browser. For instance, is your Oracle Maps application overwhelming the remote web server with too many HTTP requests for map tile and FOI images? Maybe you should look into using the Whole-Image option for your FOI layer(s) to avoid transmitting many small pieces from MapViewer to the client every time a user pans or zooms the map. We will provide more tips like this in a later blog as well.

To be continued...

1 comment:

Sebastian Ovide said...

Do you know what RealWorker is ?

10-Aug-2010 12:10:52 oracle.lbs.mapserver.core.RealWorker generateMapImage
FINER: [RealWorker] querying/rendering time: 15832ms