Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

basic execution statistics for _find #768

Merged
merged 4 commits into from
Aug 30, 2017

Conversation

willholley
Copy link
Member

Overview

Accept an "execution_stats" parameter to _find. If present, return a new "execution_stats" object in the response which contains information about the query executed. Currently, this is only
implemented for json/all_docs indexes and contains:

  • total key lookups
  • total document lookups (when include_docs=true used)
  • total quorum document lookups (when fabric doc lookups used)

Testing recommendations

Query _find with different selectors. Add "execution_stats":true to the request body and see that an "execution_stats" field is returned. Test with different index types.

This PR adds new unit tests for the execution stats and existing behaviour is already well covered by tests.

GitHub issue number

Related Pull Requests

Checklist

  • Code is written and works correctly;
  • Changes are covered by tests;
  • Documentation reflects the changes;

@@ -38,7 +38,7 @@ create(Db, Indexes, Selector, Opts) ->
Limit = couch_util:get_value(limit, Opts, mango_opts:default_limit()),
Skip = couch_util:get_value(skip, Opts, 0),
Fields = couch_util:get_value(fields, Opts, all_fields),
Bookmark = couch_util:get_value(bookmark, Opts),
Bookmark = couch_util:get_value(bookmark, Opts),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you intentionally make a whitespace change?

@@ -69,6 +69,7 @@ explain(#cursor{}=Cursor) ->
} = Cursor,
Mod = mango_idx:cursor_mod(Idx),
Opts = lists:keydelete(user_ctx, 1, Opts0),

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whitespace

% License for the specific language governing permissions and limitations under
% the License.

-record(execution_stats, {
Copy link
Contributor

@tonysun83 tonysun83 Aug 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider changing Lookup to Fetched? It's not a huge deal, but the word lookup seems indicate key range executions search execution vs rows returned.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tonysun83 ideally the key lookup counter would be as you describe - it's just not implemented that way yet (code assumes key lookups == doc lookups until we have covering indexes). Note that the current counters don't say anything about the number of rows returned - just the number of internal row / document fetches.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tonysun83 I've renamed these to xxExamined

@@ -266,6 +267,11 @@ run_find(Resp, Db, Sel, Opts) ->
mango_crud:find(Db, Sel, fun handle_doc/2, Acc0, Opts).


handle_doc({add_key, Key, Value = #execution_stats{}}, Acc0) ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should work without the need for the extra redundant code

handle_doc({add_key, Key, Value = #execution_stats{}}, Acc0) ->
    JSONValue = mango_execution_stats:to_json(Value),
    handle_doc({add_key, Key, JSONValue}, Acc0);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear to me which code is redundant here. The intent is to perform custom JSON serialisation for the execution_stats record - without that, the response is invalid (JSON serialisation fails).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what Tony is saying here is you don't need to do the lists:keystore in this function. Rather convert to json and then call handle_doc() again so that the function below will do all lists:keystore work.
I also think you could consider doing the to_json and in the cursor:execute sections. Then you don't need to add a whole new function.

assert resp["execution_stats"]["total_key_lookups"] == 3
assert resp["execution_stats"]["total_doc_lookups"] == 0
assert resp["execution_stats"]["total_quorum_doc_lookups"] == 3

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no new end of line

case mango_selector:match(Cursor#cursor.selector, Doc) of
ExecutionStats0 = mango_execution_stats:incr_key_lookups(Cursor#cursor.execution_stats),
case doc_member(Cursor#cursor.db, Props, Cursor#cursor.opts, ExecutionStats0) of
{ok, Doc, execution_stats, ExecutionStats1} ->
Copy link
Contributor

@tonysun83 tonysun83 Aug 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider changing the return value here to be:

{ok, Doc, {execution_stats, ExecutionStats1}};

The function doc_member/4 will have to be modified as well

@tonysun83
Copy link
Contributor

overall looks pretty good with some minor nitpicks.

@willholley willholley force-pushed the mango_execution_stats branch 3 times, most recently from 5d77c9f to 2843c72 Compare August 23, 2017 14:42
Copy link
Member

@garrensmith garrensmith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking awesome. Just some small changes.

@@ -105,7 +107,8 @@ execute(Cursor, UserFun, UserAcc) ->
query_args = QueryArgs,
user_fun = UserFun,
user_acc = UserAcc,
fields = Cursor#cursor.fields
fields = Cursor#cursor.fields,
execution_stats = mango_execution_stats:log_execution_start(Stats)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a bit of redundancy here with the double execution. Maybe something like mango_execution_stats:log_start. Based on the module name we know its the execution stats.

@@ -119,7 +122,7 @@ execute(Cursor, UserFun, UserAcc) ->
JsonBM = dreyfus_bookmark:pack(FinalBM),
Arg = {add_key, bookmark, JsonBM},
{_Go, FinalUserAcc} = UserFun(Arg, LastUserAcc),
{ok, FinalUserAcc}
mango_execution_stats:maybe_add_execution_stats(FinalCAcc, FinalUserAcc)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just do mango_execution_stats:maybe_add_stats

Cursor = Cursor0#cursor{
user_fun = UserFun,
user_acc = UserAcc
user_acc = UserAcc,
execution_stats = mango_execution_stats:log_execution_start(Stats)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is minor. But I wonder if this shouldn't be done in the create function rather than execute.

@@ -266,6 +267,11 @@ run_find(Resp, Db, Sel, Opts) ->
mango_crud:find(Db, Sel, fun handle_doc/2, Acc0, Opts).


handle_doc({add_key, Key, Value = #execution_stats{}}, Acc0) ->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what Tony is saying here is you don't need to do the lists:keystore in this function. Rather convert to json and then call handle_doc() again so that the function below will do all lists:keystore work.
I also think you could consider doing the to_json and in the cursor:execute sections. Then you don't need to add a whole new function.

@@ -0,0 +1,59 @@
# -*- coding: latin-1 -*-
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is needed.

Accept an "execution_stats" parameter to _find. If present, return
a new "execution_stats" object in the response which contains
information about the query executed. Currently, this is only
implemented for json/all_docs indexes and contains:
 - total keys examined (currently always 0 for json indexes)
 - total documents examined (when include_docs=true used)
 - total quorum documents examined (when fabric doc lookups used)
Include execution time in mango execution stats. Only implemented for views.
@willholley willholley force-pushed the mango_execution_stats branch 2 times, most recently from f9d8fcf to e6ac226 Compare August 24, 2017 16:41
@garrensmith garrensmith merged commit af839e1 into apache:master Aug 30, 2017
wohali pushed a commit that referenced this pull request Oct 19, 2017
Accept an "execution_stats" parameter to _find. If present, return
a new "execution_stats" object in the response which contains
information about the query executed. Currently, this is only
implemented for json/all_docs indexes and contains:
 - total keys examined (currently always 0 for json indexes)
 - total documents examined (when include_docs=true used)
 - total quorum documents examined (when fabric doc lookups used)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants