自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MongoDB范圍查詢的索引優(yōu)化

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

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

問題

比如我們進(jìn)行下面這樣的查詢:

 
  1. db.collection.find({"country": "A"}).sort({"carsOwned": 1}) 

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

 
  1. db.collection.ensureIndex({"country": 1, "carsOwned": 1}) 

我們來看一個(gè)稍微復(fù)雜一點(diǎn)的查詢:

 
  1. db.collection.find({"country": {"$in": ["A""G"]}}).sort({"carsOwned": 1}) 

這回我們是要查詢 country 為 A 或者 G 的數(shù)據(jù)條目,結(jié)果同樣按 carsOwned 字段排序。

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

原因

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

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

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

所以說上面 explain 輸出了一個(gè) “scanAndOrder” : true 的提示,就是說這次查詢,是先進(jìn)行了scan獲取到數(shù)據(jù),再進(jìn)行了獨(dú)立的排序操作的。

那如果我們使用右邊的索引來做查詢,結(jié)果就不太一樣了。我們沒有將排序字段放在***,而是放在了前面,相反把篩選字段放在了后面。那這樣的結(jié)果就是:我們會(huì)從值為1的節(jié)點(diǎn)開始遍歷(右圖的左邊一支),當(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é)果。我們通過左圖的索引需要掃描到4條記錄,然后對(duì)4條記錄進(jìn)行排序才能返回結(jié)果。而右邊只需要我們掃描2條結(jié)果就能直接返回了(因?yàn)椴樵兊倪^程就是按需要的順序去遍歷索引的)。

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

總結(jié)

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

當(dāng)查詢是:

 
  1. db.test.find({a:1,b:2}).sort({c:1}) 

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

如果查詢是:

 
  1. 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ù)情況而定。

原文鏈接:http://blog.nosqlfan.com/html/4117.html

 

【編輯推薦】

  1. 先睹為快:甲骨文NoSQL數(shù)據(jù)庫(kù)
  2. 八種主流NoSQL數(shù)據(jù)庫(kù)系統(tǒng)對(duì)比
  3. 解讀NoSQL數(shù)據(jù)庫(kù)的四大家族
  4. NoSQL在企業(yè)中的發(fā)展歷程
  5. 一個(gè)初創(chuàng)公司是否適用NoSQL引發(fā)的探討

 

 

責(zé)任編輯:彭凡 來源: NOSQLfan
相關(guān)推薦

2023-12-14 12:56:00

MongoDB數(shù)據(jù)庫(kù)優(yōu)化

2018-06-07 08:54:01

MySQL性能優(yōu)化索引

2024-04-29 08:00:00

MongoDB索引

2010-05-27 16:12:10

MySQL索引

2024-04-03 09:12:03

PostgreSQL索引數(shù)據(jù)庫(kù)

2024-09-19 08:09:37

MySQL索引數(shù)據(jù)庫(kù)

2024-01-22 09:41:05

MongoDB索引

2024-10-16 11:11:51

隔離InnoDB死鎖

2023-08-24 09:44:16

數(shù)據(jù)庫(kù)性能

2024-11-27 09:46:34

2019-05-08 14:02:52

MySQL索引查詢優(yōu)化數(shù)據(jù)庫(kù)

2018-07-11 20:07:06

數(shù)據(jù)庫(kù)MySQL索引優(yōu)化

2010-06-03 09:24:46

Oracle

2024-05-30 07:55:43

2010-10-27 13:47:50

Oracle索引

2023-08-09 08:59:14

2013-11-19 10:08:06

MongoDB

2011-08-15 18:09:46

查詢性能調(diào)優(yōu)索引優(yōu)化

2024-04-18 10:48:24

MongoDB

2023-12-18 11:21:40

MongoDB數(shù)據(jù)庫(kù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)