I will here summarize what should be known about running benchmarks with Virtuoso.
Physical Memory
For 8G RAM, in the [Parameters]
stanza of virtuoso.ini
, set —
[Parameters]
...
NumberOfBuffers = 550000
For 16G RAM, double this—
[Parameters]
...
NumberOfBuffers = 1100000
Transaction Isolation
For most cases, certainly all RDF cases, Read Committed should be the default transaction isolation. In the [Parameters]
stanza of virtuoso.ini
, set —
[Parameters]
...
DefaultIsolation = 2
Multiuser Workload
If ODBC, JDBC, or similarly connected client applications are used, there must be more ServerThreads
available than there will be client connections. In the [Parameters]
stanza of virtuoso.ini
, set —
[Parameters]
...
ServerThreads = 100
With web clients (unlike ODBC, JDBC, or similar clients), it may be justified to have fewer ServerThreads
than there are concurrent clients. The MaxKeepAlives
should be the maximum number of expected web clients. This can be more than the ServerThreads
count. In the [HTTPServer]
stanza of virtuoso.ini
, set —
[HTTPServer]
...
ServerThreads = 100
MaxKeepAlives = 1000
KeepAliveTimeout = 10
Note — The [HTTPServer] ServerThreads
are taken from the total pool made available by the [Parameters] ServerThreads
. Thus, the [Parameters] ServerThreads
should always be at least as large as (and is best set greater than) the [HTTPServer] ServerThreads
, and if using the closed-source Commercial Version, should not exceed the licensed thread count.
Disk Use
The basic rule is to use one stripe (file) per distinct physical device (not per file system), using no RAID. For example, one might stripe a database over 6 files (6 physical disks), with an initial size of 60000 pages (the files will grow as needed).
For the above described example, in the [Database]
stanza of virtuoso.ini
, set —
[Database]
...
Striping = 1
MaxCheckpointRemap = 2000000
— and in the [Striping]
stanza, on one line per SegmentName
, set —
[Striping]
...
Segment1 = 60000 , /virtdev/db/virt-seg1.db = q1 , /data1/db/virt-seg1-str2.db = q2 , /data2/db/virt-seg1-str3.db = q3 , /data3/db/virt-seg1-str4.db = q4 , /data4/db/virt-seg1-str5.db = q5 , /data5/db/virt-seg1-str6.db = q6
As can be seen here, each file gets a background IO thread (the = qxxx
clause). It should be noted that all files on the same physical device should have the same qxxx
value. This is not directly relevant to the benchmarking scenario above, because we have only one file per device, and thus only one file per IO queue.
SQL Optimization
If queries have lots of joins but access little data, as with the Berlin SPARQL Benchmark, the SQL compiler must be told not to look for better plans if the best plan so far is quicker than the compilation time expended so far. Thus, in the [Parameters]
stanza of virtuoso.ini
, set —
[Parameters]
...
StopCompilerWhenXOverRunTime = 1