Does anyone know of a way to run a query in MongoDB, and specify that a named index NOT be used?
We have multiple indexes on our data and there are situations where mongo is making a poor choice about which index to use to satisfy some types of queries. But we don't necessarily want to declare that a specific index be used. Only that we know which one is definitely a poor choice.
Using a named index is easy:
db.users.find({....}).hint( "index_name" )
Excluding a named index might look something like this:
db.users.find({....}).hint( "index_name", false)
Any insight is appreciated.
You can't exclude indexes, you can only specify the use of one.
However, MongoDB empirically tests indexes with your query by checking the search speed of the query against all indexes. It then determines what index to use based on these results. Can you please run the query with .explain(true) to show all the query plans.
Regards,
Charlie
Related
I have a collection which has an optional field xy_id. About 10% of the documents (out of 500k) does not have this xy_id field.
I have quite a lot of queries to this collection like find({xy_id: <id>}).
I tried indexing it normally (.createIndex({xy_id: 1}, {"background": true})) and it does improve the query speed.
Is this the correct way to index the field in this case? or should I be using a sparse index or another way?
Yes, this is the correct way. The default behaviour of MongoDB is serving well in this case. You can see in the docs that index creation supports an unique flag, which is false by default. All your documents missing the index key will be indexed under a single index entry. Queries can use this index in all cases because all the documents are indexed.
On the other hand, if you use sparse index the documents missing the index key will not be indexed at all. Some operations such as count, sort and other queries will not be able to use the sparse index unless explicitly hinted to do so. If explicitly hinted, you should be okay with incorrect results - the entries not in the index will be omitted in the result. You can read about it here.
I have a few questions about MongoDB:
(1) Does indexing help with projection?
(2) I have assigned a collection a number of indexes and tried to run a find with sort, and then use explain, it shows BtreeCursor index on the sorted field.
Could it be that the other indexes have helped in the query part and explain just didn't show it because it shows only the last index that helped the find?
Or explain should show all indexes that assisted in querying, sorting, etc?
Thanks.
Does indexing helps in projection?
I believe the only time it will really help (defined by performance etc) is if the query is "covered": http://docs.mongodb.org/manual/tutorial/create-indexes-to-support-queries/
So for example, if you wanted to query on {d:1, e:2} and get back {_id, t, e}, you would do:
db.t.ensureIndex({d:1 , e:1, _id:1, t:1});
db.t.find({d:1, e:2}, {_id:1, t:1, e:1});
And that query's explain() output would show indexOnly as true meaning that it never loaded documents from disk to return a response.
So yes, indexes can help with projection under certain circumstances.
I have assigned a collection a number of indexes and tried to run a find with sort, and then use explain, it shows BtreeCursor index on the sorted field.
Yes it does.
Could it be that the other indexes have helped in the query part and explain just didn't show it because it shows only the last index that helped the find?
If you are a victim of index intersectioning then you would use an explain(true) to show all index plans that were used.
It is good to note that separate indexes are not used for find and sort with intersectioning, so the answer here is actually no: http://docs.mongodb.org/manual/core/index-intersection/#index-intersection-and-sort
In mongo, When creating an index I am trying to figure out whether the following query would have an index on a) category_ids and status, OR b) category_ids, status and name???
Source.where(category_ids: [1,2,3], status: Status::ACTIVE).order_by(:name) # ((Ruby/Mongoid code))
Essentially, I am trying to figure out whether indexes should include the ORDER_BY columns? or only the WHERE clauses? Where could I read some more about this?
Yes, an index on thius particular query would be beneficial to the speed of the query. However there is one caveat here, the order of the index fields.
I have noticed you are using an $in there on category_ids. This link is particularly useful in understanding a little complexity which exists from using an $in with an index on the sort (or a sort in general in fact): http://blog.mongolab.com/2012/06/cardinal-ins/
Towards the end it gives you an indea of an optimal index order for your type of query:
The order of fields in an index should be:
First, fields on which you will query for exact values.
Second, fields on which you will sort.
Finally, fields on which you will query for a range of values.
For reference a couple of other helpful links are as follows:
http://docs.mongodb.org/manual/applications/indexes/
http://docs.mongodb.org/manual/faq/indexes/#how-do-you-determine-what-fields-to-index
http://jasonwilder.com/blog/2012/02/08/optimizing-mongodb-indexes/
why does direction of index matter in MongoDB?
And, http://www.slideshare.net/kbanker/mongo-indexoptimizationprimer
These will help you get started on optimising your indexes and making them work for your queries.
What are the advantages we get from compound indexes. I mean suppose we have a collection, in which I have to index over 2 fields say key1 and key2. How different is it from having a compound index {key1:1, key2:1}. Whats the problem with having 2 separate indexes. Can't mongodb make use of 2 or more indexes to satisfy a query.
As at MongoDB 2.2:
Every query, including update operations, use one and only one index.
The query optimizer selects the index empirically by occasionally running alternate query plans and by selecting the plan with the best response time for each query type.
An exception to the above rule is $or queries; each clause is executed in parallel and can use a separate index.
For more information see:
Indexing Overview
Query Optimizer
Explain
I am running a query like the following:
db.sales.find({location: "LLLA",
created_at: {$gt: ISODate('2012-07-27T00:00:00Z')}}).
sort({created_at: -1}).limit(3)
This query is working as expected, but its not performing fast enough. I have an index on the location field, and a separate index on the created_at field. Please let me know if you see me missing something obvious here to make it faster.
Thanks for your time on this.
Mongo won't use two indexes for a given query, if you want filter by location and sort by created_at you can add a compound index:
db.sales.ensureIndex({location: 1, created_at: -1})
You should run explain on your queries when you have issues like that. Sort in particular causes non-intuitive complications with indexing, and the explain command can occasionally make it obvious why.
It's also worth noting that you can usually sort by _id to approximate insert time (assuming auto generated ObjectId values), but that won't help you as much as a compound index will in this case since you're filtering on an additional field.
just use IDs:
db.sales.find({location: "LLLA"}).sort({_id: -1}).limit(3)