SORT命令 LIMIT參數 BY參數 GET參數 STORE參數 排序性能優化 很多場合需要對元素進行排序,這時除了使用有序集合外,還可以藉助Redis提供的SORT命令來排序。 SORT命令 SORT命令可以對列表類型、集合類型和有序集合類型的鍵進行排序。 SORT key SORT key D ...
- SORT命令
- LIMIT參數
- BY參數
- GET參數
- STORE參數
- 排序性能優化
很多場合需要對元素進行排序,這時除了使用有序集合外,還可以藉助Redis提供的SORT命令來排序。
SORT命令
SORT命令可以對列表類型、集合類型和有序集合類型的鍵進行排序。
SORT key
SORT key DESC
SORT key ALPHA
SORT命令會根據元素自身的值進行排序,在對有序集合類型排序時會忽略元素的分數。
預設按從小到大的順序排列,增加DESC參數可以按照倒序排列。
如果元素為非數字,增加ALPHA參數可以按照字典順序排列。如果直接對非數字元素排序會報錯:
(error)ERR One or more scores can't be converted into double
如果沒有加ALPHA參數的話,SORT命令會嘗試將所有元素轉換成雙精度浮點數來比較,如果無法轉換則會提示錯誤。
LIMIT參數
如果返回結果數量較多需要分頁,可以使用LIMIT參數
SORT key DESC LIMIT offset count
表示在排序結果中,跳過前offset個元素,獲取之後的count個元素。
BY參數
很多情況下列表(或集合、有序集合)中存儲的元素值代表的是對象的ID,單純對這些ID自身排序有時意義並不大。更多的時候會希望根據ID對應的對象的某個屬性進行排序。
這種情況下可以使用BY參數:
SORT key BY reference
其中reference表示排序的參考鍵,會根據參考鍵的值來排序,而不再是列表或集合中元素自身的值。
比如:
SORT tag:ruby:posts BY post:* -> time DESC
這裡tag:ruby:posts存儲了文章的ID,post:*為散列類型,其中的time欄位為文章的發佈時間,這樣就可以將文章ID根據發佈時間排序了。執行的時候,對每個元素使用元素的值替換參考鍵中的第一個“*”並獲取其值,然後依據該值對元素排序。
上面是基於散列類型排序的寫法,基於字元串排序更簡單:
SORT sortbylist BY itemscore:* -> time DESC
BY參數排序有下麵幾種特殊情況:
- 當參考鍵名不包含“*”時(即常量鍵名,與元素值無關),SORT命令將不會執行排序操作,因為Redis認為這種情況是沒有意義的(所有要比較的值都一樣)。
- 如果幾個元素的參考鍵值相同,則SORT命令會再比較元素本身的值來決定元素的順序。
- 當某個元素的參考鍵不存在時,會預設參考鍵的值為0。
GET參數
SORT命令預設返回的是鍵本身的元素被排序後的結果,而使用GET參數可以指定返回鍵值。
比如前面按照文章發佈時間排序後,並不僅僅獲得文章ID,而是更進一步獲取文章的標題,可以這樣寫:
SORT tag:ruby:posts BY post:* -> time DESC GET post:*->title
而且,在一個SORT命令中可以使用多個GET參數(BY參數只能有一個):
SORT tag:ruby:posts BY post:* -> time DESC GET post:*-> title GET post:* -> time
如果仍然需要文章的ID,可以使用GET #:
SORT tag:ruby:posts BY post:* -> time DESC GET post:*-> title GET post:* -> time GET #
這樣最終的結果就包含了文章的標題、發佈時間和ID。
STORE參數
預設情況下SORT會直接返回排序結果,如果希望保存排序結果,可以使用STORE參數,比如要把排序的結果保存到sort.result鍵中:
SORT tag:ruby:posts BY post:* -> time DESC STORE sort.result
保存後的鍵的類型為列表類型,如果鍵已經存在則會覆蓋它。加上STORE參數後SORT命令的返回值為結果的個數。
實際使用中,常常將STORE命令與之前學過的EXPIRE結合,來緩存排序的結果。
排序性能優化
SORT是Redis中最強大最複雜的命令之一,但如果使用不好也很容易成為性能的瓶頸。
SORT命令的時間複雜度是O(n+mLog m),其中:
- n表示要排序的列表(集合或有序集合)中的元素個數
- m表示要返回的元素個數
當n較大的時候SORT命令的性能相對較低,並且Redis在排序前會建立一個長度為n的容器來存儲待排序的元素,雖然是一個臨時的過程,但如果同時進行較多的大數據量排序操作則會嚴重影響性能。
所以在使用SORT命令時要註意這幾點:
- 減小n,儘量減少待排序鍵中元素的數量;
- 減少m,使用LIMIT參數只獲取需要的數據;
- 如果排序的數據量較大,經常需要排序,可以使用STORE和EXPIRE將結果緩存起來。