redis命令效率分析
append:時間複雜度為o(1),如果鍵已經存在並且是字串,則此命令將在字串末尾追加值。如果鍵不存在,則建立它並將其設定為空字串,因此在這種特殊情況下,追加將類似於SET。返回修改後的字串長度。
- 字串
Redis中最基本的資料結構就是字串,使用redis最簡單的額方法就是字串作為鍵值儲存。這裡的字串是經過序列化之後儲存的。操作字串最基礎的GET和SET命令都是O(1)的效率。非常快速和簡單,是效率最高的儲存形式。而GETRANGE、MSET、MGET都是O(n)的效率。
- 雜湊
這裡的雜湊和程式語言中的字典或關聯陣列類似,是一種將一個或多個欄位對映到對應的值的資料結構。在Redis中,所有的雜湊值必須是Redis字串,並且有唯一的鍵名,鍵的值是簡單的Redis字串。通過呼叫Redis的HGET或HMGET命令,傳入合適的鍵和值,就能返回欄位值。大多數場景下,Redis雜湊可以為HSET和HGET提供很棒的O(1)效能。而HGETALL、HMSET、HMGET、HKEYS和HVALS都為O(n)。如果雜湊非常小,HMGET和HGETALL沒有明顯差異,但是當雜湊鍵值不斷增長時,HMGET將會表現更好,它們雖然都是O(n)效率,但是HMGET的複雜度上限為所請求的欄位的總和而不是整個雜湊。在雜湊總體較小時,使用HMGET代替HGETALL比較好,但在大型雜湊來說,返回大量資料的HMGET命令會在完成執行前阻塞其他客戶端接收資料,從而極大影響Redis總體效能。這種時候,針對性的HGET會是更好的選擇。
- 列表
Redis中列表是字串的有序集合,它允許重複的字串值。Redis中的列表是以連結串列實現的。使用LPUSH和RPUTH向列表首尾新增元素是簡單的操作,表現為常數複雜度O(1),對於LINSERT和LSET命令來說,時間複雜度是線性O(n),但這兩者有一些重要的差別,對LSET來說,你可以指定下標值設定列表的值,由於本質上是連結串列,因此變數n是列表的長度,不管是設定第一項還是最後一項,時間複雜度都是O(1),對於LINSERT來說,你可以在參考值之前或之後插入值,時間複雜度為O(n),n為列表元素個數,該命令必須從頭查到尾,最壞情況是查到列表末尾。對於LRANGE來說,官方文件給的複雜度是O(s+n),其中s為列表的表頭或表尾到偏移量位置的元素個數,者取決於列表大小,n代表返回的元素總數。通常來講,LTRIM命令的時間複雜度為O(n),其中n為返回給客戶端的元素數量。使用LTRIM結合RPUTH或LPUTH是儲存固定長度集合的常用方法。
- 集合
Redis中的集合保證了字串值得唯一性,但是不保證順序。Redis集合支援集合語義的並集,交集和差集,並在Redis中將這些集合操作的結果儲存為一個新的Redis集合。SADD將一個或多個值新增到集合中,時間複雜度為O(n),其中n為新增到集合中的元素總數。重要的SISMEMBER命令用於判斷值是否為集合成員,時間複雜度為O(1),用於返回集合中所有成員列表,時間複雜度為O(n)。它的集合操作是最有價值的地方,SUNION和SUNIONSTORE命令允許將多個集合的所有成員返回給客戶端或儲存為Redis中的新集合。這兩個命令的時間複雜度為O(n),其中n為所有集合中的元素總數。SINTER和SINTERSTORE命令返回集合的交集,後者會儲存在Redis中,多個集合的公共成員計算時間複雜度為O(n*m),其中n是最小集合的大小,m為集合總數。最後SDIFF和SDIFFSTORE命令將返回或儲存兩個集合的差異。和SUNION相同,SDIFF和SDIFFSTORE的時間複雜度為O(n),n為集合元素總數。
- 位串和位操作
Redis字串和對應命令的特殊用法允許為Redis中相對較少的位元使用該記憶體高效的資料結構。在位串中,每個位元組儲存8位,其中位置0位最高有效位,Redis位串最大為512Mb,這個redis所有的鍵和值限制是一樣的。位串高效的原因是大多數針對它的命令都是O(1)和O(n),使用SETBIT和GETBIT命令,可以將位設定0或1,這兩個的時間複雜度都是O(1),位串對於儲存一些列連續二進位制資訊及其迅速。BITOP,BITPOS,BITCOUNT的時間複雜度為O(N),但是提供了強大的語義。如果使用Redis儲存業務儀表盤,每月每天甚至每小時的使用資訊能夠很高效的完成。