Benchmarks results stored to the database

I’ve just added some functionality to Swingbench that I probably should have added a long time ago. Now, every time you run a benchmark using Charbench, Swingbench or Minibench, the results will we saved to the database. This provides an archive of all of your benchmarks and makes it easy to perform comparisons between runs. These results can be trivially queried using SQL via Oracle’s support for dot notation. You will need an Oracle Database 19c or higher version for this functionality to work.

For example after running the SOE benchmark you can query the BENCHMARK_RESULTS table with a piece of SQL similar to the following

select *
from BENCHMARK_RESULTS

You should see something similar to

   ID RECORDING_TIME                  RECORDING_NAME                          RESULTS_JSON
_____ _______________________________ _______________________________________ ______________________
   61 14-APR-25 17.05.59.237226000    "Order Entry (PLSQL) V2" - Charbench    {"Results":{"xmlns":"http://www.dominicgiles.co....
   62 14-APR-25 17.07.03.775729000    "Order Entry (PLSQL) V2" - Charbench    {"Results":{"xmlns":"http://www.dominicgiles.co....
   63 14-APR-25 17.16.22.020068000    "Order Entry (PLSQL) V2" - Charbench    {"Results":{"xmlns":"http://www.dominicgiles.co....

Whilst this is useful we can use SQL support for JSON dot notation to look at the results in a little more detail..

select id,
       RECORDING_TIME,
       br.RESULTS_JSON.Results.Overview.AverageTransactionsPerSecond
from BENCHMARK_RESULTS br;

The dot notation syntax enables us to navigate through the hierarchy of the JSON document. In this instance we are using to retrieve the average transactions per second as shown in the snippet of the json document.

{
  "Results": {
    "xmlns": "http://www.dominicgiles.com/swingbench/results",
    "Overview": {
      "Comment": "Simple Order Entry benchmark using client side jdbc calls",
      "TotalLogonTime": "0:00:00",
      "TotalRunTime": "1:00:00",
      "TotalCompletedTransactions": "145018",
      "TotalFailedTransactions": "0",
      "BenchmarkName": "Order Entry (jdbc)",
      "AverageTransactionsPerSecond": "40.28",
      "TimeOfRun": "8 Apr 2025, 12:21:19",
      "MaximumTransactionRate": "3674"
    },

Using a similar approach we can compare the difference in performance between each run.

select br.id,
       br.RECORDING_TIME,
    json_value(br.RESULTS_JSON, '$.Results.Overview.AverageTransactionsPerSecond' RETURNING NUMBER) AS AverageTPS,
       ROUND(
               (
                   json_value(br.RESULTS_JSON, '$.Results.Overview.AverageTransactionsPerSecond' RETURNING NUMBER) -
                   LAG(json_value(br.RESULTS_JSON, '$.Results.Overview.AverageTransactionsPerSecond' RETURNING NUMBER), 1)
                       OVER (ORDER BY RECORDING_TIME)
                   ) /
               NULLIF(
                       LAG(json_value(br.RESULTS_JSON, '$.Results.Overview.AverageTransactionsPerSecond' RETURNING NUMBER), 1)
                       OVER (ORDER BY RECORDING_TIME), 0
               ) *
               100, 2
       ) "Percentage Difference from Previous"
from BENCHMARK_RESULTS br

Which gives us the following.

   ID RECORDING_TIME                     AVERAGETPS    Percentage Difference from Previous 
_____ _______________________________ _____________ ______________________________________ 
   86 15-APR-25 13.36.03.438917000           183.27                                        
   87 15-APR-25 13.36.41.229173000           284.13                                  55.03 
   88 15-APR-25 13.37.37.215548000            656.6                                 131.09

It’s also possible to de-nest the results from the individual transactions using SQL syntax similar to the following.

SELECT jt.* FROM SOE.BENCHMARK_RESULTS b,
    JSON_TABLE (
            b.RESULTS_JSON FORMAT JSON,
            '$.Results.TransactionResults.Result[*]'
            COLUMNS (
                id VARCHAR2(255) PATH '$.id',
                AverageResponse NUMBER PATH '$.AverageResponse',
                FiftythPercentile NUMBER PATH '$.FiftythPercentile'
                )
    ) jt
where b.ID = 88;

Which produces the following output for the JSON Document with an id of 88

ID                               AVERAGERESPONSE    FIFTYTHPERCENTILE 
__________________________ _____________________ ____________________ 
Customer Registration          13.95774075579033                   10 
Update Customer Details        6.322704081632653                    3 
Browse Products                7.997188139059305                    5 
Order Products                 17.94081893793986                   13 
Process Orders                 12.31829268292683                    9 
Browse Orders                 10.467011642949547                    8 

The introduction of JSON adds a huge amount of flexibility to analyzing the results of benchmark runs without the need to parse XML or JSON files.

Other than this feature you can now also ask for the results file in json format with the new -oj command line parameter (defaults to xml). There’s also some fixes and the inclusion of the latest Oracle Database 23ai jdbc drivers.

You can download the latest version here or from github

2025

Benchmarks results stored to the database

2 minute read

I’ve just added some functionality to Swingbench that I probably should have added a long time ago. Now, every time you run a benchmark using Charbench, Swin...

Back to Top ↑

2024

Back to Top ↑

2023

New functionality for swingbench…

4 minute read

A small but significant set of changes Last weekend I updated swingbench to add a few features that I’ve had frequent requests for. One is the addition of da...

Swingbench 2.7 June 2023 Update

less than 1 minute read

A new build of Swingbench with a whole bunch of small changes mainly related to the benchmarks. Faster build time for the JSON benchmark when creating lar...

Size Makes A Difference

6 minute read

In my previous post “Going Big” I discussed the difference testing a data set of a representative size can make to the usefulness of a benchmark. Running a w...

Going Big

9 minute read

Swingbench makes it simple to generate a dataset that you can simulate transactions against. However one of the problems I commonly see is that the users of ...

Back to Top ↑

2022

Swingbench 2.7

1 minute read

Swingbench 2.7 So I finally found some time to get a new build of swingbench done. The big change is that swingbench now only supports JDK-17 and above. Now,...

A new build of DB Time Monitor

less than 1 minute read

Following quickly on the heels of the update to MonitorDB I’m releasing a new build of DBTimeMonitor. This is a simple update using the latest Oracle jdbc dr...

A new build of MonitorDB

less than 1 minute read

I’ve just updated MonitorDB. It’s never going to replace Grafana but if you need a quick solution to monitor a few values inside of the Oracle Database and y...

Making Colour work on the Command Line for Windows

less than 1 minute read

I’ll make a confession. I don’t own a Microsoft Windows Machine. I never have and probably never will. This means that I generally never get the oppertunity ...

A New Release of Swingbench

2 minute read

A New Release of Swingbench… Along with a new website, I’m rolling out a new build of Swingbench. This release is a little embarrassing for me, as it include...

A New Look

2 minute read

A New Start… Quite a lot has changed since I last posted on this website. I had just left Oracle to join Google… A year and a half later I returned to Oracle...

Back to Top ↑