skip to Main Content

Given a single instance redis which supports lua scripts. Is there any performance difference between calling ‘mget’ once and calling ‘get’ multiple times to retrieve the value of multiple keys?

2

Answers


  1. It will be different in some cases.

    MGET key [key …] Time complexity: O(N) where N is the number of keys to retrieve.
    GET key Time complexity: O(1)

    According to time complexity, GET is more efficient.
    However, there is a difference between passing a single command to redis and passing it multiple times.
    If you don’t use pool, the difference is even greater.

    Of course, what I would recommend is to use it depending on the type of data you want to deal with.
    You decide whether it’s more efficient to manage your data in Maps.

    Login or Signup to reply.
  2. Time-complexity-wise, both result in the same: O(N) = N*O(1).

    But there is overhead associated with processing each command and parsing the result back to Lua. So MGET will give you better performance.

    You can measure this. The following scripts receive a list of keys, one calls GET multiple times, the other one calls MGET.

    Calling GET multiple times:

    local t0 = redis.call('TIME')
    local res = {}
    for i = 1,table.getn(KEYS),1 do 
        res[i] = redis.call('GET', KEYS[i])
    end
    local t1 = redis.call('TIME')
    local micros = (t1[1]-t0[1])*1000000 + t1[2]-t0[2]
    table.insert(res,'Time taken: '..micros..' microseconds')
    table.insert(res,'T0: '..t0[1]..string.format('%06d', t0[2]))
    table.insert(res,'T1: '..t1[1]..string.format('%06d', t1[2]))
    return res
    

    Calling MGET once:

    local t0 = redis.call('TIME')
    local res = redis.call('MGET', unpack(KEYS))
    local t1 = redis.call('TIME')
    local micros = (t1[1]-t0[1])*1000000 + t1[2]-t0[2]
    table.insert(res,'Time taken: '..micros..' microseconds')
    table.insert(res,'T0: '..t0[1]..string.format('%06d', t0[2]))
    table.insert(res,'T1: '..t1[1]..string.format('%06d', t1[2]))
    return res
    

    Calling GET multiple times took 51 microseconds, vs MGET once 20 microseconds:

    > EVAL "local t0 = redis.call('TIME') n local res = {} n for i = 1,table.getn(KEYS),1 do  n     res[i] = redis.call('GET', KEYS[i]) n end n local t1 = redis.call('TIME') n local micros = (t1[1]-t0[1])*1000000 + t1[2]-t0[2] n table.insert(res,'Time taken: '..micros..' microseconds') n table.insert(res,'T0: '..t0[1]..string.format('%06d', t0[2])) n table.insert(res,'T1: '..t1[1]..string.format('%06d', t1[2])) n return res" 10 key:1 key:2 key:3 key:4 key:5 key:6 key:7 key:8 key:9 key:10
     1) "value:1"
     2) "value:2"
     3) "value:3"
     4) "value:4"
     5) "value:5"
     6) "value:6"
     7) "value:7"
     8) "value:8"
     9) "value:9"
    10) "value:10"
    11) "Time taken: 51 microseconds"
    12) "T0: 1581664542637472"
    13) "T1: 1581664542637523"
    > EVAL "local t0 = redis.call('TIME') n local res = redis.call('MGET', unpack(KEYS)) n local t1 = redis.call('TIME') n local micros = (t1[1]-t0[1])*1000000 + t1[2]-t0[2] n table.insert(res,'Time taken: '..micros..' microseconds') n table.insert(res,'T0: '..t0[1]..string.format('%06d', t0[2])) n table.insert(res,'T1: '..t1[1]..string.format('%06d', t1[2])) n return res" 10 key:1 key:2 key:3 key:4 key:5 key:6 key:7 key:8 key:9 key:10
     1) "value:1"
     2) "value:2"
     3) "value:3"
     4) "value:4"
     5) "value:5"
     6) "value:6"
     7) "value:7"
     8) "value:8"
     9) "value:9"
    10) "value:10"
    11) "Time taken: 20 microseconds"
    12) "T0: 1581664667232092"
    13) "T1: 1581664667232112"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search