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 dbreeze.tiesky.com
Alexey Solovyov < hhblaze@gmail.com >
Ivars Sudmalis < zikills@gmail.com >
Here is represented a brief overview of a condensed experience, helping to tune DBreeze interaction to achieve maximal performance.
Instantiate DBreeze instance once
Instantiate DBreezeEngine once in your assembly as an internally accessible static variable and use it from different threads.
Use one commit in the end of transaction
Make many operations inside of one transaction, then finalize all of them 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.
Select-Insert-Select-Insert...
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.
VaueLazyLoadingIsOn
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 without 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
tran.SynchronizeTables("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;
maxId++;
//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.
Like
ntCustomerEntity.Technical_SetTable_OverwriteIsNotAllowed();
Or/And
ntCustomerIndex1.Technical_SetTable_OverwriteIsNotAllowed();
NOT ON table Customers.
For maxId it’s good always to be overwritten.