[SERVER-9899] Performance of JavaScript Stored Function on MongoDB Server Created: 11/Jun/13  Updated: 10/Dec/14  Resolved: 25/Jun/13

Status: Closed
Project: Core Server
Component/s: JavaScript, Performance
Affects Version/s: debugging with submitter
Fix Version/s: None

Type: Question Priority: Major - P3
Reporter: Abhishek Kumar Assignee: Andy Schwerin
Resolution: Done Votes: 0
Labels: javascript, mongodb, performance
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Linux


Issue Links:
Duplicate
is duplicated by SERVER-9898 Performance of JavaScript Stored Func... Closed
Participants:

 Description   

This is related to javascript stored function in mongodb server. I know all the details about the working and use cases. I am doubtful about one line which is in the official documentation of MongoDB.

"Note : We do not recommend using server-side stored functions if possible."

After moving to V8 JavaScript engine ( improving concurrency issues for javascript queries ) and given the fact this may save us many network round trip time, why this is not recommended?

Also, if there some performance difference in running javascript queries Vs running normal queries ( given both are able to use index ) ?

Please link me to supported documentation. Also, it will be much useful, if the reason for such statements are also mentioned in the documentation.



 Comments   
Comment by Andy Schwerin [ 14/Jun/13 ]

It is not a statement about the current implementation, but a statement about what may be in the future. I do not know of any specific reason why performance would differ between a query run in an eval and one run over the network, today.

Comment by Abhishek Kumar [ 14/Jun/13 ]

Is it possible to elaborate on this part, may be using some example?

Comment by Andy Schwerin [ 14/Jun/13 ]

The two situations may have different locking behavior, but do not necessarily.

Comment by Abhishek Kumar [ 14/Jun/13 ]

Just want to confirm what I understood is correct.
The normal read and read lock acquired using eval is having some difference. The read lock of eval having 'typical database locking behavior' is little expensive.

Comment by Andy Schwerin [ 13/Jun/13 ]

The "nolock" argument to eval causes a more typical database locking behavior to apply. The query execution engine may yield the read lock periodically. As to your last question, I recommend conducting the same experiment again, to convince yourself, but queries without a $where component will not use javascript evaluation to test each document.

Comment by Abhishek Kumar [ 12/Jun/13 ]

Thanks for making me understand the difference. I run the test as you told, and clearly seeing the big difference in response time.

Please let me know, if eval with nolock option, yields the read lock or not? The documentation is not having this information.
Also if there are normal read queries inside the eval, are they treated as JavaScript queries or normal queries?

Comment by Andy Schwerin [ 11/Jun/13 ]

There will be a performance difference in the two queries that you describe. Both of them will be able to use the {{

{a: 1}

}} index, but the form that uses $where to examine the value of b will pay a constant factor overhead for invoking javascript execution on documents that match a. I recommend that you construct a simple collection of a few hundred thousand documents, where a few tens of thousands have {{

{a: 1}

}}, and compare performance of the two queries, to get a sense for the amount of overhead. Of course, if the expression you wish to compare is not expressible in the current version of the query language, you may have to use $where form. It is typically worth avoiding, however.

Comment by Abhishek Kumar [ 11/Jun/13 ]

@Andy
Thanks for the comment.
Here, from your comment, I understand the restriction, so might be because of that it is not recommended. Also, I want to know if there is some performance related differences also exists with a JavaScript query Vs normal query. Say, for below example:
db.collection.ensureIndex(

{ a : 1 }

)
db.collection.find(

{ a : 1, b : 1 }

)
db.collection.find(

{ a : 1, $where : "this.b=1"}

)

Comment by Andy Schwerin [ 11/Jun/13 ]
  1. Stored javascript functions can only issue queries when executed via the "eval" command, which requires full administrative permissions in MongoDB 2.4 (http://docs.mongodb.org/manual/reference/command/eval/).
  2. The "eval" command is not compatible with sharded collections.
  3. Stored functions are not compatible (to my knowledge) with sharded mapreduce, though I may be mistaken, here.
Generated at Thu Feb 08 03:21:46 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.