A few minor updates to OCI*ML:
oraprefetchto set rows pre-fetched and buffered by OCI. This is set per-statement handle, with a default for newly-created handles set in.ocamlinit.oradeqtimeto set the number of seconds to wait onoradequeueoperations. Set to -1 (the default) for indefinite wait. RaisesNot_foundif no message is received within the timeout period.orabindexecchanged to take a list ofCol_valuearraysrows_affectedpopulated in statement handles for DML- Included
.ocamlinitfor use withocimlsh.
Using a representative test for pre-fetching, querying a 5000-row result set over a VPN connection from a 1G Debian VM on my Mac to a test database at corporate HQ about 20 miles away† (with a pre-warmed block buffer cache):
| Prefetch | Time (s) | Rows/sec | Speedup factor |
|---|---|---|---|
| 1 | 94.93 | 52.6 | 1 |
| 10 | 20.41 | 244.98 | 4.65 |
| 50 | 8.50 | 588.24 | 11.17 |
| 100 | 7.10 | 704.23 | 13.37 |
| 500 | 4.84 | 1033.06 | 19.61 |
| 1000 | 5.99 | 834.72 | 15.85 |
This shows a nearly 20× improvement from 10 lines of code and a bit of experimental tuning! The tradeoff is obviously memory consumption; two copies of the rows will exist in memory when using orafetchall – one in the OCI cache, and one in a list in OCaml.
With some assistance on SO, I have also added a prompt to the toplevel, this is a feature I always use in SQL*Plus™ to make sure I don’t run the wrong command on the wrong database! Of course, unlike sqlplus, ocimlsh can have many open connections; I am not sure how to best represent that.
† As the crow flies; it’s ~36ms measured by ping and ~70ms measured by tnsping due to firewalls most likely.


Pingback: OCI*ML: Support for RETURNING | So I decided to take my work back underground
Pingback: OCI*ML: Bulk Operations | So I decided to take my work back underground
Pingback: OCaml 4 beta | So I decided to take my work back underground