I thought it’s time to give you an overview of how the internals of SisoDb works so that you get some insight into “performance” considerations.
How is data stored?
Before continuing, lets give a quick intro to SisoDb. SisoDb is a NoSql influenced provider giving you a document-oriented solution over Sql-server. It does this by seing your object graphs as structures (document in a NoSql document-oriented database) where public members of simple types (strings, numbers, dates etc) in the hierarchy are made queryable. As a default every property of the graph in the contract of the passed class or interface is flattened to fit one row in a special “Indexes-table”. This table is there for making queries against your structure. You can easily go in and place indexes on the columns you query a lot. All values are extracted using cached delegates generated using IL-Generator emits, hence I don’t relly on dirty, timeconsuming reflection calls.
The structure is also stored as Json in the “Structure-table”. This is done to keep an intact schemaless representaion of your structure so that structures can be reindexed and to give an effective deserialization process when performing queries.
I’m using one of the fastest Json-serializer I know of in the .Net community: ServiceStack.Text you can read about a performance compare between the popular Json.Net library here: Json.Net vs ServiceStack.Text.
Not making everything queryable?
I’m currently implementing support for this, where you will be able to specify “hey don’t make eveything queryable, since I will only query on these properties”. That way you can boost performance making the “Indexes-table” much more slimmer.
This feature is coming really soon, perhaps it’s already implemented.
Separated entities & sharding
Since data is document-oriented one certain structure gets it’s own tables and they stand on their own legs not having relations to other tables. This is also a mindset you need to have when working with SisoDb, a mindset that it’s not an O/RM over a relational data model, it’s a document-database. You could take advantage of this and shard your model. I’m planning support for this in the future, but right now you will manually need to put up a proxy accessing different SisoDb instances depending on the type of structure being consumed.
Use replication for readmodels and writemodels
Since I’m targetting SQL-server you get some built in benefits where you could take advantage of the builtin support for replicating data between databases. This way you could easily have a write and a read store as well as put up a store which you then use some ETL tool to transform the data to a model more fit for reporting, warehousing etc.
How is data inserted?
When inserting entities there is a demand that you have a property named “SisoId”. That is the only demand SisoDb has on your model. That property could either return an Integer or an Guid.
In this scenario SisoDb looks how many entities you are inserting and reservers a range of identities and assign them to the model before performing the insert to the database. This way no ineffective insert + select for each row have to be made (as with Entity framework or traditional identities in NHibernate).
Sequential Guid identities
SisoDb doesn’t use traditional generated Guids but instead it uses sequential guids mimicking the algorithm used in SQL Server’s sequential guids.
I make use of custom datareader that reads over the structures and is consumed by the SQL bulkcopy. That way there are “NO custom generated ad-hoc batch SQL inserts” but effective inserts using the bulk copy.
When querying using uow.Where or uow.Query or uow.Get etc. your specified lambda expression are translated to parameterized SQL executed as a plain select via the ADO.Net command and NOT executed using ad-hoc SQL and the EXEC function in SQL server.
Well that was a short overview of how the internals works. Will be glad to try and answer any questions. There are more information about it here: http://sisodb.com/docs