亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪(fǎng)問(wèn)板塊 發(fā)新帖
查看: 2322 | 回復(fù): 1
打印 上一主題 下一主題

[MongoDB] MongoDB范圍查詢(xún)的索引優(yōu)化 [復(fù)制鏈接]

論壇徽章:
6
CU大;照
日期:2013-03-14 14:14:08CU大牛徽章
日期:2013-03-14 14:14:26CU大牛徽章
日期:2013-03-14 14:14:29處女座
日期:2014-04-21 11:51:59辰龍
日期:2014-05-12 09:15:10NBA常規(guī)賽紀(jì)念章
日期:2015-05-04 22:32:03
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2012-11-07 15:01 |只看該作者 |倒序?yàn)g覽
本帖最后由 wang290 于 2012-11-07 15:02 編輯

我們知道,MongoDB索引是B-Tree結(jié)構(gòu)的,和MySQL的索引非常類(lèi)似。所以你應(yīng)該聽(tīng)過(guò)這樣的建議:創(chuàng)建索引的時(shí)候要考慮到sort操作,盡量把sort操作要用到的字段放到你的索引后面。但是有的情況下,這樣做反而會(huì)使你的查詢(xún)性能更低。

問(wèn)題比如我們進(jìn)行下面這樣的查詢(xún):

db.collection.find({"country": "A"}).sort({"carsOwned": 1})查詢(xún)條件是 {“country”: “A”},按 carsOwned 字段的正序排序。所以索引就很好建了,直接建立 country , carsOwned 兩個(gè)字段的聯(lián)合索引即可。像這樣:

db.collection.ensureIndex({"country": 1, "carsOwned": 1})我們來(lái)看一個(gè)稍微復(fù)雜一點(diǎn)的查詢(xún):

db.collection.find({"country": {"$in": ["A", "G"]}}).sort({"carsOwned": 1})這回我們是要查詢(xún) country 為 A 或者 G 的數(shù)據(jù)條目,結(jié)果同樣按 carsOwned 字段排序。

如果我們還使用上面的索引,并且使用 explain() 分析一下這個(gè)查詢(xún),就會(huì)發(fā)現(xiàn)在輸出中有一個(gè) “scanAndOrder” : true 的字段,并且 nscanned 的值可能會(huì)比想象中的大很多,甚至指定了 limit 也沒(méi)什么效果。

原因這是什么原因呢,我們先看下面這張圖:


如上圖所未,左邊一個(gè)是按 {“country”: 1, “carsOwned”: 1} 的順序建立的索引。而右邊是按 {“carsOwned”: 1, ”country”: 1} 順序建立的索引。

如果我們執(zhí)行上面的查詢(xún),通過(guò)左邊的索引,我們需要將 country 值為A的(左圖的左邊一支)所有子節(jié)點(diǎn)以及country 值為G的(左圖的右邊一支)所有子節(jié)點(diǎn)都取也來(lái)。然后再對(duì)取出來(lái)的這些數(shù)據(jù)按 carsOwned 值進(jìn)行一次排序操作。

所以說(shuō)上面 explain 輸出了一個(gè) “scanAndOrder” : true 的提示,就是說(shuō)這次查詢(xún),是先進(jìn)行了scan獲取到數(shù)據(jù),再進(jìn)行了獨(dú)立的排序操作的。
那如果我們使用右邊的索引來(lái)做查詢(xún),結(jié)果就不太一樣了。我們沒(méi)有將排序字段放在最后,而是放在了前面,相反把篩選字段放在了后面。那這樣的結(jié)果就是:我們會(huì)從值為1的節(jié)點(diǎn)開(kāi)始遍歷(右圖的左邊一支),當(dāng)發(fā)現(xiàn)有 country 值為 A 或 G 的,就直接放到結(jié)果集中。當(dāng)完成指定數(shù)量(指定 limit 個(gè)數(shù))的查找后。我們就可以直接將結(jié)果返回了,因?yàn)檫@時(shí)候,所有的結(jié)果本身就是按 carsOwned 正序排列的。

對(duì)于上面的數(shù)據(jù)集,如果我們需要2條結(jié)果。我們通過(guò)左圖的索引需要掃描到4條記錄,然后對(duì)4條記錄進(jìn)行排序才能返回結(jié)果。而右邊只需要我們掃描2條結(jié)果就能直接返回了(因?yàn)椴樵?xún)的過(guò)程就是按需要的順序去遍歷索引的)。

所以,在有范圍查詢(xún)(包括$in, $gt, $lt 等等)的時(shí)候,其實(shí)刻意在后面追加排序索引通常是沒(méi)有效果的。因?yàn)樵谶M(jìn)行范圍查詢(xún)的過(guò)程中,我們得到的結(jié)果集本身并不是按追加的這個(gè)字段來(lái)排的,還需要進(jìn)行一次額外的排序才行。而在這種情況下,可能反序建立索引(排序字段在前、范圍查詢(xún)字段在后)反而會(huì)是一個(gè)比較優(yōu)的選擇。當(dāng)然,是否更優(yōu)也和具體的數(shù)據(jù)集有關(guān)。

總結(jié)總結(jié)一下,舉兩個(gè)栗子。

當(dāng)查詢(xún)是:

db.test.find({a:1,b:2}).sort({c:1})那么直接建立 {a:1, b:1, c:1} 或者 {b:1, a:1, c:1} 的聯(lián)合索引即可。

如果查詢(xún)是:

db.test.find({a:1,b:{$in:[1,2]}}).sort({c:1})那么可能建立 {a:1, c:1, b:1} 的聯(lián)合索引會(huì)比較合適。當(dāng)然,這里只是提供了多一種思路,具體是否采用還是需要視你的數(shù)據(jù)情況而定。
來(lái)源:architects.dzone.com

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2012-12-04 13:08 |只看該作者
想請(qǐng)問(wèn)一下mongo的關(guān)鍵字模糊查詢(xún)效率如何呢
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專(zhuān)區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP