2013-12-17 128 views
3

我有一個聯繫人列表應用程序使用mongoDB來存儲聯繫人和java驅動程序與數據庫接口。每個聯繫人都有自己的文檔,其中包含許多字段,包括GivenName,Surname和MiddleInitial。MongoDB查詢性能問題

我最近增加了150,000個額外的聯繫人,這會降低性能。我添加了Surname/GivenName/MiddleInitial(用於按姓氏排序和搜索)的索引,另一個用於GivenName(用於由GivenName進行搜索)。這在大多數情況下都有幫助,除少數情況外。所有搜索都是固定在字符串開頭的正則表達式(例如^ Ale。*)。

當用名字進行搜索時,以q,u,x或z開頭的查詢比其他任何字母顯着慢;按姓氏搜索得到的第一個字母越接近z越慢。我一直無法找到這類問題的其他例子。任何幫助表示讚賞。

編輯:

這裏有指標:

collection.ensureIndex(new BasicDBObject("Surname",1).append("GivenName",1).append("MiddleInitial",1)); 
collection.ensureIndex(new BasicDBObject("GivenName", 1)); 

和查詢:

BasicDBObject contactInfo = new BasicDBObject("GivenName", new BasicDBObject("$regex", "(?i)^al.*"); //GivenName may be Surname, al is just an example query 

DBCursor cursor = collection.find(contactInfo).sort(new BasicDBObject("Surname",1).append("GivenName", 1).append("MiddleInitial", 1)); 

解釋結果AZ上給定名稱are here

解釋結果AZ上給定名稱沒有排序are here

+2

使用explain方法運行查詢,查看以'a'作爲前綴並以'z'作爲前綴運行時是否有區別。有關詳細信息,請參見http://docs.mongodb.org/manual/reference/method/cursor.explain/ –

+0

我剛剛在姓氏上運行了一個for a,n和z。唯一的區別是nscanned和nscannedallplans字段(分別爲30,97964和152633)和milis字段,但這只是查詢所需的時間,因此它應該是不同的。 – prototypetolyfe

+2

添加有關正在使用的查詢和索引的更多信息可能很有用 –

回答

2

您正在執行不區分大小寫的正則表達式搜索。這幾乎肯定會繞過您定義的任何索引。一種選擇是將字段存儲兩次,一次複製到大寫/小寫,然後對此進行正則表達式查詢。 start-with查詢仍然可以使用索引,但如果忽略這種情況,則不適用。

+0

修復了速度問題。我會找出區分大小寫的解決方法。謝謝 – prototypetolyfe