garrensmith commented on a change in pull request #2410: Mango metrics
URL: https://github.com/apache/couchdb/pull/2410#discussion_r364260299
 
 

 ##########
 File path: src/mango/src/mango_cursor.erl
 ##########
 @@ -146,44 +146,87 @@ group_indexes_by_type(Indexes) ->
     end, ?CURSOR_MODULES).
 
 
-maybe_add_warning(UserFun, #cursor{index = Index, opts = Opts}, UserAcc) ->
-    NoIndexWarning = case Index#idx.type of
-        <<"special">> ->
-            <<"no matching index found, create an index to optimize query 
time">>;
+% warn if the _all_docs index was used to fulfil a query
+no_index_warning(#idx{type = Type}) when Type =:= <<"special">> ->
+    couch_stats:increment_counter([mango, unindexed_queries]),
+    [<<"No matching index found, create an index to optimize query time.">>];
+no_index_warning(_) ->
+    [].
+
+
+% warn if user specified an index which doesn't exist or isn't valid
+% for the selector.
+% In this scenario, Mango will ignore the index hint and auto-select an index.
+invalid_index_warning(Index, Opts) ->
+    UseIndex = lists:keyfind(use_index, 1, Opts),
+    invalid_index_warning_int(Index, UseIndex).
+
+
+invalid_index_warning_int(Index, {use_index, [DesignId]}) ->
+    case filter_indexes([Index], DesignId) of
+        [] ->
+            couch_stats:increment_counter([mango, query_invalid_index]),
+            Reason = fmt("_design/~s was not used because it does not contain 
a valid index for this query.",
+                [ddoc_name(DesignId)]),
+            [Reason];
         _ ->
-            ok
-    end,
+            []
+    end;
+invalid_index_warning_int(Index, {use_index, [DesignId, ViewName]}) ->
+    case filter_indexes([Index], DesignId, ViewName) of
+        [] ->
+            couch_stats:increment_counter([mango, query_invalid_index]),
+            Reason = fmt("_design/~s, ~s was not used because it is not a 
valid index for this query.",
+                [ddoc_name(DesignId), ViewName]),
+            [Reason];
+        _ ->
+            []
+    end;
+invalid_index_warning_int(_, _) ->
+    [].
 
-    UseIndexInvalidWarning = case lists:keyfind(use_index, 1, Opts) of
-        {use_index, []} ->
-            NoIndexWarning;
-        {use_index, [DesignId]} ->
-            case filter_indexes([Index], DesignId) of
-                [] ->
-                    fmt("_design/~s was not used because it does not contain a 
valid index for this query.", 
-                        [ddoc_name(DesignId)]);
-                _ ->
-                    NoIndexWarning
-            end;
-        {use_index, [DesignId, ViewName]} ->
-            case filter_indexes([Index], DesignId, ViewName) of
-                [] ->
-                    fmt("_design/~s, ~s was not used because it is not a valid 
index for this query.", 
-                        [ddoc_name(DesignId), ViewName]);
-                _ ->
-                    NoIndexWarning
-            end
-    end,
 
-    maybe_add_warning_int(UseIndexInvalidWarning, UserFun, UserAcc).
+% warn if a large number of documents needed to be scanned per result
+% returned, implying a lot of in-memory filtering
+index_scan_warning(#execution_stats {
+                    totalDocsExamined = Docs,
+                    totalQuorumDocsExamined = DocsQuorum,
+                    resultsReturned = ResultCount
+                }) ->
+    % Docs and DocsQuorum are mutually exclusive so it's safe to sum them
+    DocsScanned = Docs + DocsQuorum,
+    Ratio = index_scan_ratio(DocsScanned, ResultCount),
+    Threshold = config:get("mango", "index_scan_warning_threshold", 10),
+    index_scan_warning_int(Threshold, Ratio).
 
 
-maybe_add_warning_int(ok, _, UserAcc) ->
-   UserAcc;
+index_scan_ratio(DocsScanned, 0) ->
+    DocsScanned;
+index_scan_ratio(DocsScanned, ResultCount) ->
+    DocsScanned / ResultCount.
 
-maybe_add_warning_int(Warning, UserFun, UserAcc) ->
-    couch_stats:increment_counter([mango, unindexed_queries]),
-    Arg = {add_key, warning, Warning},
+
+index_scan_warning_int(Threshold, Ratio) when is_integer(Threshold), Threshold 
> 0, Ratio > Threshold ->
+    couch_stats:increment_counter([mango, too_many_docs_scanned]),
+    Reason = <<"The number of documents examined is high in proportion to the 
number of results returned. Consider adding a more specific index to improve 
this.">>,
+    [Reason];
+index_scan_warning_int(_, _) ->
+    [].
+
+
+maybe_add_warning(UserFun, #cursor{index = Index, opts = Opts}, Stats, 
UserAcc) ->
+    W0 = invalid_index_warning(Index, Opts),
+    W1 = no_index_warning(Index),
+    W2 = index_scan_warning(Stats),
+    Warnings = lists:append([W0, W1, W2]),
+    maybe_add_warning_int(Warnings, UserFun, UserAcc).
+
+
+maybe_add_warning_int([], _, UserAcc) ->
 
 Review comment:
   Can you move this function above all the functions that it calls. That makes 
it easier to follow.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to