Ok looking at the source, it appears that there isn’t any getMulti option. Wondering why, I took a look at the source for 2.5 and apparently getMulti is just a sequence of singular gets, so basically just sugar, and I can perhaps see why it was implemented in 3.0.
I find this mindblowing actually. I’d always assumed getMulti is better than Select * from app use Keys but not really. Presumably the query engine will do a better job of a parallelizing the document getting than I can in my node environment.
The Node.js is optimized to pipeline and batch individual operations together internally. When you perform a large number of operations simultaneously, these are all batched together to a single group of operations that are sent to the server to be executed. We take advantage of this internal behaviour in our getMulti implementation, which is why you see in 2.x we didn’t need to do anything special and also why we dropped it from the 3.x SDKs.
Your example of using Promise.all is dead on. For instance, in the following example, both calls would take pretty much an identical period of time, as both calls only essentially execute 1 network call:
var result = await bucket.get('somekey1')
var result = await Promise.all([
Your model of the server’s performance is actually backwards from reality. In the case of using N1QL to perform your operation, it needs to then go out to the KV nodes to execute those operations anyways which adds additional round-trip time to your request, and N1QL cannot batch any better than the SDKs (which makes sense since they actually use the SDKs). If you already know which keys you want to access, directly performing those operations via KV will be vastly faster than performing them via N1QL.
I’m trying to put together a demo for some colleagues to illustrate among other things the upshot of this discussion, and so I wrote the attached script to demo the timing differences between the query vs direct approach.
I’m getting strange results in that it seems the performance is practically exactly the same, meaning timing results within single digit ms and with which approach coming in first being completely hit or miss.
The topology is a straightforward 1 query node, 1 data node deployment, with both nodes on separate AWS spot instances.
The only explanation I can conjure is that since I’m testing over fios (pinging the query node/data node results in 10-20ms) the network hop gain is counter balanced by some overhead in the node sdk batching process vs the c/go/whatever form of the sdk that the query engine uses. But I am also trying with large doc payloads, which slows the timings down across the test runs (and should exacerbate the extra network hop cost) but am getting the same roughly equivalent performance statistics as above.
Can you take a look at my small script and maybe shed a bit of light about where my approach went wrong?
You are correct that over a WAN to the server, the performance difference would be negligible between KV or N1QL as N1QL <-> KV would be <1ms, whereas your WAN is 10-20m. So the performance impact is effectively hidden in the jitter of the WAN network.
Its really a new thing for me that When you perform a large number of operations simultaneously, these are all batched together to a single group of operations that are sent to the server to be executed
Can please share a reference link of any documentation where it is mentioned?