Proposal: add some sort of "production" mode to disable costly sanity checks
I was investigating the performance of some recursive .getJoin() queries and noticed that thinky does a lot of run-time sanity checking. This is very useful when developing and testing but comes at the cost of performance. When running in production where we can make reasonable assumptions about the integrity of the data already stored it would be useful to turn some of those checks off.
For example, looking at the hasOne case in /lib/query.js#L321-L343, I noticed a roughly 1.5x performance increase by removing the run-time checking:
self._query = self._query.merge(function(doc) {
var result = r.table(joins[key].model.getTableName()).getAll(doc(joins[key].leftKey), {index: joins[key].rightKey}).nth(0).default({});
var innerQuery = new Query(joins[key].model, result);
if ((modelToGet[key] != null) && (typeof modelToGet[key]._apply === 'function')) {
innerQuery = modelToGet[key]._apply(innerQuery);
}
return r.branch(
doc.hasFields(joins[key].leftKey),
r.object(key, innerQuery.getJoin(modelToGet[key], getAll, gotModel)._query),
{}
)
});
@marshall007 -- you are missing a line in your modifications:
innerQuery = innerQuery.getJoin(modelToGet[key], getAll, gotModel)._query;
This makes the joins recursive like if you do
A.hasOne(B, ...)
B.hasOne(C, ...)
A.getJoin({b: {c: true}});
That's probably what explain the difference (and not just the r.branch - r.branch should be just a if statement in the server, so I can't imagine that being slow).
@neumino I was thinking it's actually the multiple .count() queries that make it slow, but I'll look into it a bit more.
[edit]: and unless I'm misunderstanding I moved the .getJoin() down into the r.object(...) but I think that still behaves the same.
The count should be relatively cheap. It's count on an array that is in memory.
But maybe there's a big. How big are your arrays?
Well this is a hasOne so the array length is always 1 in this case, is that what you're asking? In terms of total documents, the "left" table has about 10k documents and I'm joining (with hasOne) to a table that has ~300 documents.