Professional, open-source, NoSql (embedded Key/Value storage), transactional, ACID-compliant, multi-threaded object database management system for .NET 3.5> MONO.

Written in C#.

Copyright ©  2012

Alexey Solovyov < >

Ivars Sudmalis < >

Here is represented a brief overview of a condensed experience, helping to tune DBreeze interaction to achieve maximal performance.

Use one commit in the end of transaction

Make many operations inside of one transaction, then finalize all of than with one Commit.

Insert sorted ascending in-memory

Insert data sorted ascending in memory. Internally DBreeze is built up to work in most efficient way exactly using such approach.


In Select-Insert-Select-Insert... one table sequence, use Select with a flag asReadVisibilityScope. DBreeze opens 2 parallel cursors on one table and technically they work much faster than one cursor jumping between Select and Insert sequences.


Set VaueLazyLoadingIsOn = false, when you need to get Keys with values, this flag reads Key with the value at once. By default this flag is set to true and reads value only when it’s called, e.g. row.Value

tran.SynchronizeTables as synchronizer

tran.SynchronizeTables works as a thread synchronizer and can be used among .NET program even withouth database operations

using (var tran = M.CRM.DBEngine.GetTransaction())


                //All necessary reads -> set of tables

                tran.SynchronizeTables("set of tables"); //all writing threads into similar tables will wait here until current transaction is finished

Updating values on the same place or in the end of file

Updating values and putting them on the same physical place helps to economize HDD space, but can make the speed of the bulk operation hundred times slower. That’s why we use such command, telling DBreeze put updated data physically to the the end of file - this boosts update speed.

tran.Technical_SetTable_OverwriteIsNotAllowed("table name")

tran.Insert<>(“table name”,,,,);

tran.Insert<>(“table name”,,,,);

Size of the table will be bigger, but the speed of operation will be huge.

One of typical data patterns is a root table containing  MaxId row,  data and secondary indicies in nested table.

Let’s assume table customer:

using (var tran = engine.GetTransaction())

                //We want to modify table Customers


//Under index new byte[]{0} we will store monotonically grown Id of Customers

      long maxId=tran.Select<byte[],long>(“Customers”, new byte[]{0}).Value;

//Under index new byte[]{1} we will store Nested Table containing Customer Entity itself

        //we want to modify that’s why InsertTable not SelectTable

        var ntCustomerEntity = tran.InsertTable<byte[]>("Customers", new byte[]{1}, 0);

//Under index new byte[]{2} we will store Nested Table containing Secondary Index CreatedDate for example      

        var ntCustomerIndex1 = tran.InsertTable<byte[]>("Customers", new byte[]{2}, 0);

So, if we want to make really fast update operations with one of those nested tables, we should call Technical_SetTable_OverwriteIsNotAllowed exactly on these nested tables.





NOT ON table Customers.

For maxId it’s good always to be overwritten.