溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

使用索引來排序查詢結(jié)果

發(fā)布時(shí)間:2020-07-04 13:56:53 來源:網(wǎng)絡(luò) 閱讀:2312 作者:UltraSQL 欄目:MongoDB數(shù)據(jù)庫

使用索引來排序查詢結(jié)果


MongoDB中,排序操作可以通過從索引中按照索引順序獲取文檔的方式來保證結(jié)果的有序性。如果查詢計(jì)劃器(planner)無法從索引中得到排序順序,那么它將需要在內(nèi)存中排序結(jié)果。相比于不使用索引的排序操作,使用索引會(huì)有更好的性能。此外,如果 不使用 索引的排序操作使用了超過32M的內(nèi)存,那么操作會(huì)終止。


使用單鍵索引排序


如果一個(gè)遞增或遞減索引是單鍵索引,那么在該鍵上的排序操作可以是任意方向。


例如,在集合 records 的 a 鍵上創(chuàng)建遞增的索引:

db.records.ensureIndex( { a: 1 } )

索引可以支持在 a 上的遞增排序:

db.records.find().sort( { a: 1 } )

索引也支持如下在 a 上的遞減排序,通過以相反的順序遍歷索引的方式:

db.records.find().sort( { a: -1 } )


在多個(gè)鍵上排序


創(chuàng)建 復(fù)合索引 以支持在多個(gè)鍵上排序。


您可以指定在索引的所有鍵或者部分鍵上排序。但是,排序鍵的順序必須和它們在索引中的排列順序 一致 。例如,索引 { a: 1, b: 1 } 可以支持排序 { a: 1, b: 1 } 但不支持 { b: 1, a: 1 } 排序。


此外,sort中指定的所有鍵的排序順序(例如遞增/遞減)必須和索引中的對應(yīng)鍵的排序順序 完全相同, 或者 完全相反 。例如,索引 { a: 1, b: 1 } 可以支持排序 { a: 1, b: 1 } 和排序 { a: -1, b: -1 } ,但 不支持 排序 { a: -1, b: 1 } 。


排序與索引前綴


如果排序的鍵符合索引的鍵或者 前綴 ,那么MongoDB可以使用索引來排序查詢結(jié)果。復(fù)合索引的前綴是指被索引鍵的子集,由一個(gè)或多個(gè)排在最開始的鍵組成。


例如,在集合 data 上創(chuàng)建一個(gè)復(fù)合索引:

db.data.ensureIndex( { a:1, b: 1, c: 1, d: 1 } )

那么,該索引的前綴如下:

{ a: 1 }   
{ a: 1, b: 1 }    
{ a: 1, b: 1, c: 1 }

如下查詢和排序操作可以使用索引前綴來排序查詢結(jié)果。這些操作不需要在內(nèi)存中對結(jié)果集排序。


例子      索引前綴  

db.data.find().sort( { a: 1 } )     { a: 1 }    
db.data.find().sort( { a: -1 } )     { a: 1 }    
db.data.find().sort( { a: 1, b: 1 } )     { a: 1, b: 1 }    
db.data.find().sort( { a: -1, b: -1 } )     { a: 1, b: 1 }    
db.data.find().sort( { a: 1, b: 1, c: 1 } )     { a: 1, b: 1, c: 1 }    
db.data.find( { a: { $gt: 4 } } ).sort( { a: 1, b: 1 } )     { a: 1, b: 1 }

假設(shè)有如下例子,索引的前綴鍵出現(xiàn)在查詢條件和排序中:

db.data.find( { a: { $gt: 4 } } ).sort( { a: 1, b: 1 } )

在這種情況下,MongoDB可以使用索引按照sort指定的順序來獲取文檔。如例子中所示,在查詢條件中的索引前綴可以和在sort中出現(xiàn)的前綴不一樣。


用非前綴的索引鍵排序


索引也支持使用非前綴的鍵來排序。在這種情況下,對于索引中排列在排序鍵的前面的所有鍵,查詢語句中必須包含針對它們的 相等匹配 的條件。

例如,集合 data 有如下索引:

{ a: 1, b: 1, c: 1, d: 1 }

如下操作可以使用索引來排序:

例子      索引前綴  

db.data.find( { a: 5 } ).sort( { b: 1, c: 1 } )     { a: 1 , b: 1, c: 1 }    
db.data.find( { b: 3, a: 4 } ).sort( { c: 1 } )     { a: 1, b: 1, c: 1 }    
db.data.find( { a: 5, b: { $lt: 3} } ).sort( { b: 1 } )     { a: 1, b: 1 }

如最后一個(gè)操作所示,只有索引中那些排列在排序鍵 前面 的鍵必須在查詢語句中有相等匹配條件;其他索引鍵則可以指定其他匹配條件。


如果查詢語句 沒有 對排列在排序鍵前面或者與之有所重疊的前綴鍵指定相等匹配條件,那么操作將 不會(huì) 有效使用索引。例如,如下操作指定了排序 { c: 1 } ,但是查詢語句并沒有對前綴鍵 a 和 b 指定相等匹配:

db.data.find( { a: { $gt: 2 } } ).sort( { c: 1 } )   
db.data.find( { c: 5 } ).sort( { c: 1 } )

這些操作 將不會(huì) 高效地使用索引 { a: 1, b: 1, c: 1, d: 1 } ,且可能甚至不會(huì)使用該索引來獲取文檔。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI