davisp commented on a change in pull request #469: Choose index based on fields
match
URL: https://github.com/apache/couchdb/pull/469#discussion_r109720398
##########
File path: src/mango/src/mango_cursor_view.erl
##########
@@ -107,10 +107,14 @@ execute(#cursor{db = Db, index = Idx} = Cursor0,
UserFun, UserAcc) ->
% check FieldRanges for a, b, c, and d and return
% the longest prefix of columns found.
composite_indexes(Indexes, FieldRanges) ->
- lists:foldl(fun(Idx, Acc) ->
+ FieldKeys = [Key || {Key, _} <- FieldRanges],
+ SortedIndexes = lists:foldl(fun(Idx, Acc) ->
Cols = mango_idx:columns(Idx),
Prefix = composite_prefix(Cols, FieldRanges),
- [{Idx, Prefix} | Acc]
+ % create a score based on how close the number of fields
+ % the index has to the number of fields in the selector
+ Score = length(Cols) - length(FieldKeys),
Review comment:
To expand on this, there are three things we're contemplating here:
1. Number of {Field, Range} pairs in the selector.
2. Number of columns in the index
3. The shared prefix between those two.
The important case to remember here is that the selector may have more
fields than are being satisfied by the index. Ie, a selector may only use the
first one or two out of a three column index.
Which means that if you have a selector that has more fields than the index
has columns it ends up having a negative score which seems.... odd. However,
what we're really caring about here is that we're being the least specific once
we have some part of an index satisfied. Its bit odd given that we also want
the longest prefix. So the sort in words is basically something like:
I want to use the index with the most matching fields to my selector, but
with the least extra fields not used by my selector (ie, the smallest
length(Cols) - length(Prefix)).
Though that leaves us with the same current connundrum when we have two
indexes with the same number of columns but sharing a common prefix with the
selector. (the [a, b, c], [a, d, e] example I mentioned).
For that case I'd still change it away from the docid sort since that's
rather ambiguous and generally not supplied by the user and as such is
essentially random (ie, its a hash which is hard to predict, its not uuid
random though (if memory serves)).
Anyway, so I'd use the length preference you've got and then break ties with
the field name past the end of the sort and then I guess fall back to docid if
we have two indices that have the same set of columns cause it shouldn't matter?
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on 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